Web Storage System Software Development Kit

Microsoft Web Storage System Software Development Kit

This documentation assists developers in building solutions on the Web Storage System, a new database technology that manages heterogeneous data and was designed specifically for Web-based development. Microsoft® Exchange 2000 Server is the first product that uses the Web Storage System.

  • Understanding the Web Storage System introduces you to the Web Storage System and its data storage and data access features.
  • Core Web Storage System Tasks describes tasks that are commonly used when accessing the Web Storage System.
  • Development Environment describes how to set up your programming environment for developing applications for Exchange 2000 Server.
  • Building Solutions on the Web Storage System provides information, such as programming tasks and sample source code, to help you build applications commonly used on the Web Storage System.
  • Developer Resources explains the tool set provided by Microsoft for working with Exchange 2000 Server.
  • Reference contains information about object models and APIs to use when building applications for the Web Storage System.
  • Release Notes for Exchange 2000 Server contains the latest information about programming for Exchange 2000 Server.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Legal Information

Information in this document, including URL and other Internet Web site references, is subject to change without notice. Unless otherwise noted, the example companies, organizations, products, people and events depicted herein are fictitious and no association with any real company, organization, product, person or event is intended or should be inferred. Complying with all applicable copyright laws is the responsibility of the user. Without limiting the rights under copyright, no part of this document may be reproduced, stored in or introduced into a retrieval system, or transmitted in any form or by any means (electronic, mechanical, photocopying, recording, or otherwise), or for any purpose, without the express written permission of Microsoft Corporation.

Microsoft may have patents, patent applications, trademarks, copyrights, or other intellectual property rights covering subject matter in this document. Except as expressly provided in any written license agreement from Microsoft, the furnishing of this document does not give you any license to these patents, trademarks, copyrights, or other intellectual property.

© 2000-2001 Microsoft Corporation. All rights reserved.

Microsoft, Active Directory, ActiveX, BackOffice, FrontPage, JScript, MSDN, MS-DOS, Outlook, PowerPoint, Visual Basic, Visual C++, Visual InterDev, Visual J++, Visual Studio, Windows, Windows NT, and Win32 are either registered trademarks or trademarks of Microsoft Corporation in the United States and/or other countries/regions.

The names of actual companies and products mentioned herein may be the trademarks of their respective owners.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Understanding the Web Storage System

The topics in this section describe how to access the Web Storage System, work with its folders and items, and develop Web Storage System applications.

Frequently Asked Questions

Introduction to the Web Storage System

Accessing the Web Storage System

Constructing Web Storage System URLs

Web Storage System Item Properties

Collaboration Data Objects

Web Storage System Search

Web Storage System Schema

Web Storage System Security

Web Storage System Events

Using Property and Full-Text Indexing

Appendixes

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Frequently Asked Questions

This topic covers the most frequently asked questions about programming with the Web Storage System.

Web Storage System

  • How do I get all properties for all items using SELECT *?

  • What type of URL should I use: file or http?

  • Does MAPI still work?

  • Do MAPI forms still work?

  • How do I hide items from Outlook?

  • What's changed in the security model for the Web Storage System?

  • Why can't I search or index certain properties?

How do I get all properties for all items using SELECT *?

You cannot get all properties for all items, because each item in the folder could conceivably have different properties. When running SELECT * commands on a folder, you receive only the list of properties that are defined by the schema for the folder. To get all the properties for a particular item, bind to it directly using Microsoft® ActiveX® Data Objects (ADO), CDO, OLE DB, or WebDAV. For more information, see Web Storage System Schema.

What type of URL should I use: file or http?

When using the Exchange OLE DB (ExOLEDB) provider, you can use URLs from either the file or http schemes. For example, the following URL format is used to access items in public stores:

http://server.domain.tld/vroot/path/to/item
file://./backofficestorage/domain/top-level-public-folder-name/path/to/item

To access mailbox stores, use this format:

http://server.domain.tld/exchange/user-alias/path
file://./backofficestorage/domain/MBX/user-alias/path

When using the file URL namespace, you do not need to explicitly specify the provider binder used to bind the item. The ExOLEDB provider is registered for this namespace. However, the provider binder for the Microsoft OLE DB Provider for Internet Publishing (MSDAIPP) OLE DB provider registers for the http URL namespace. To avoid using the wrong provider, you should always explicitly build and use an ADO Connection object with the designated ExOLEDB Provider. For example:

Dim Rec as New Record
Dim Conn as New Connection
Conn.Provider = "ExOLEDB.DataSource"
Conn.Open URL
Rec.Open URL, Conn
....

Using the http URL namespace with the ExOLEDB provider is recommended for most applications, because http URLs are used by the MSDAIPP provider and with WebDAV. In addition, you can use the same URLs between applications and reuse the same URL building code. Event handling applications, however, should use file URLs.

The MSDAIPP OLE DB provider is currently not supported for use with CDO for Microsoft® Exchange 2000 Server. Additionally, the MSDAIPP provider relies on the WinInet API to manage remote HTTP connections. The WinInet API is currently not supported for server-side applications. Therefore, use of the MSDAIPP provider is also not supported in server-side applications.

You need a separate Connection object to bind to items in different Web Storage System mailbox and public stores. To avoid poor performance, you should reuse these Connection objects whenever possible. For example:

Dim Conn1 as New ADODB.Connection
Dim Conn2 as New ADODB.Connection

' Assume /vroot1 is mapped to one public store and
'        /vroot2 is mapped to another.
Conn1.Provider="exoledb.datasource"
Conn1.Open "http://servername/vroot1"

Conn2.Provider="exoledb.datasource"
Conn2.Open "http://servername/vroot2"

Dim Rec as New Record
Rec.Open "http://servername/vroot1/folder1/item.eml", Conn1, adModeReadWrite
Rec.Close
'...
Rec.Open "http://servername/vroot_2/folder2/item2.eml", Conn2, adModeReadWrite

Does MAPI still work?

Yes. Exchange 2000 Server still supports MAPI and other technologies based on it, like CDO 1.2.1. All mailboxes hosted on an Exchange 2000 Server can be transparently accessed using MAPI, regardless of which mailbox store they are contained in.

However, only one public store and associated public folder tree can be accessed using MAPI. Administrators designate this public folder tree for " MAPI Clients" such as Microsoft® Outlook® and the Microsoft Exchange client. When viewed through a client such as Outlook 2000, this public folder tree comprises the "Public Folders" node in the client's folder list. All other public folder trees in other public stores can be accessed only by using the new mechanisms and protocols, such as the OLE DB provider, the WebDAV protocol, or the file system.

Do MAPI forms still work?

Yes. All forms written using Microsoft® Visual C++® and MAPI will continue to function as before. See the previous FAQ for more information about MAPI and Exchange 2000 Server.

How do I hide items from Outlook?

The Web Storage System defines the DAV:ishidden property to indicate that an item is not intended to be displayed to clients in a standard application. However, the Messaging API defined a separate method for hiding items in folders. In MAPI, you hide an item by placing it in the folder's associated contents table.

To hide items that are accessible to MAPI clients such as Outlook, you must set the http://schemas.microsoft.com/mapi/proptag/0x67aa000b property to true when the item is created. If the flag is not set when the item is first created, you cannot hide it later from MAPI clients.

To guarantee that this property is set when the item is first created, use a transaction to create the item. When creating the item using the WebDAV protocol, you must use the PROPPATCH command and set this property in that command. You cannot first create the item using a PUT command.

The following example uses ADO to create an item in the Web Storage System that is hidden from MAPI clients:

Dim Conn as New ADODB.Connection
Dim Rec as New ADODB.Record
Dim Flds as ADODB.Fields
Conn.Provider = "ExOLEDB.DataSource"
Conn.Open URL
Conn.BeginTrans
Rec.Open URL, Conn, adModeReadWrite, adCreateNonCollection
Set Flds = Rec.Fields
Flds("http://schemas.microsoft.com/mapi/proptag/x67aa000b") = True
Flds("DAV:ishidden") = True
' Set other fields
Flds.Update
Conn.CommitTrans

What's changed in the security model for the Web Storage System?

The Web Storage System supports folder, item, and property level access control and stores this information based on the Microsoft® Windows® 2000 security descriptor format. This means that applications can secure any item in the Web Storage System and properties of these items using both grant and deny access control entries using Windows 2000 security principals directly. For backward compatibility, the per-folder MAPI PR_ACL_TABLE format is still supported. For more information, see Web Storage System Security.

The Web Storage System provides access to an item's security descriptor through an Extensible Markup Language (XML) format. For more information, see Web Storage System Security. This format enables application developers to read and write item security descriptors by using only XML. Any client with the proper access rights that has the Microsoft MSXML COM component can read, modify and write security descriptors for Web Storage System items. The MSXML COM component is part of Microsoft® Internet Explorer 5 and provides many XML-related tools, including the XMLDOM class (for manipulating XML documents) and the XMLHTTP class (for accessing resources using WebDAV).

Why can't I search or index certain properties?

For some properties, such as DAV:href, the Web Storage System calculates them but does not persist them. However some of these propertes are cached and can be accessed by a search or be indexed

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Introduction to the Web Storage System

The Web Storage System is a database technology that you can use to store, share, and manage heterogeneous data, such as e-mail messages, Web pages, multimedia files, and Microsoft® Office 2000 documents. The Web Storage System is organized, much like a traditional file system, in a hierarchy of folders. Each folder in the Web Storage System can contain any number of items, including other folders. You can access items in the Web Storage System using many protocols and application programming interfaces (APIs), including HTTP and World Wide Web Distributed Authoring and Versioning (WebDAV), Microsoft® ActiveX® Data Objects (ADO) 2.5, OLE DB 2.5, CDO for Microsoft® Exchange 2000 Server (CDOEX), MAPI, through the file system, and by using other industry-standard wire protocols.

The following topics describe the fundamental components of the Web Storage System:

  • Web Storage System Access APIs and Protocols discusses the various network protocols and APIs you can use to access data stored in the Web Storage System.
  • Web Storage System Item Properties discusses item properties and how they are used for items in the Web Storage System.
  • Web Storage System Schema discusses the Web Storage System schema mechanism and what this mechanism has to offer developers as they build Exchange 2000 Server—based applications.
  • Web Storage System Search discusses the Web Storage System search engine and how Structured Query Language (SQL) search commands are structured and used.
  • Web Storage System Search Folders discusses the Search Folder feature of the Web Storage System, which is available through the WebDAV protocol.
  • Web Storage System Security discusses the security and access control features of the Web Storage System.
  • Building Web Storage System Forms discusses the Forms feature of the Web Storage System HTML.
  • Web Storage System Events discusses the Events feature of the Web Storage System.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Accessing the Web Storage System

Earlier versions of Microsoft® Exchange Server provided access to items in stores using MAPI. With the Web Storage System, several new application programming interfaces (APIs) and protocols are available for accessing items and item properties.

The Exchange OLE DB provider is available on the server, enabling you to use Microsoft® ActiveX® Data Objects (ADO) 2.5 and CDO for Exchange 2000 Server (CDOEX) in your server-side applications. Such applications include Active Server Pages (ASP), COM+ components, and Web Storage System event sinks.

You can also use the Microsoft OLE DB Provider for Internet Publishing (MSDAIPP) for remote access to the Web Storage System using ADO or OLE DB. CDO, however, does not support MSDAIPP for remote access.

The Web Storage System also provides access using the HTTP protocol. This industry-standard protocol has been enhanced through the WebDAV specification to support an additional set of protocol commands, such as MOVE, COPY, DELETE, and MKCOL. More important, you can request or set properties for items using the PROPFIND, PROPPATCH, and SEARCH commands. The format for transferring property data is Extensible Markup Language (XML).

For many applications, access to an item's content—but not its properties—is all that is required. You can access item streams using the Microsoft® Win32® file APIs. All public and private stores are available through the native operating system's file system. You cannot access an item's properties through the file system. To access these, you must use the Exchange OLE DB provider, WebDAV, or MAPI.

The following topics introduce you to the APIs and protocols provided by the Web Storage System:

Accessing the Web Storage System as a Database

WebDAV Access

File System Access

MAPI Access

Additional Web Storage System Access Protocols

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Accessing the Web Storage System as a Database

Microsoft® Exchange 2000 Server provides a new, high-performance OLE DB provider that you can use on the local server to access Web Storage System items using OLE DB, Microsoft® ActiveX® Data Objects (ADO) 2.5, and CDO.

The Exchange OLE DB (ExOLEDB) is a server-side component, and therefore it can be used only to access public information stores and mailbox stores that reside locally on the server. The ExOLEDB provider is ideal for use in COM+ components, Active Server Pages (ASP), and Web Storage System event sinks that run on the server. To access remote public information stores and mailbox stores, use the WebDAV protocol, a shared file system, or MAPI and components based on this technology, such as CDO 1.2.1.

Exchange registers this provider for the file URL namespace with the OLE DB 2.5 root binder on the local server. The root binder eliminates the requirement that you explicitly specify an ADO Connection object when accessing items through OLE DB. This means that you can bind an ADO Record object directly to an item only by using a file-type URL. To bind to items by using the HTTP URL scheme through the ExOLEDB provider, you must specify the ExOLEDB provider binder with an ADO Connection object (_Connection.Provider = "ExOLEDB.DataSource"). In most cases, it is best that you specify this provider explicitly to avoid needing to figure out whether an ADO Connection object is required to bind an item using ExOLEDB.

The following sections summarize how specific ADO 2.5 objects can be used effectively in Web Storage System applications.

Record

Use the Record object to access any item in the Web Storage System. You have full access to the item's set of properties and its associated stream. For example:
Dim Rec As New ADODB.Record
Dim Conn as New ADODB.Connection
Dim Stm as ADODB.Stream
Conn.Provider = "ExOLEDB.DataSource"
Conn.Open "http://server/folder"
Rec.Open "http://server/folder/item.txt", Conn
Set Stm = Rec.Fields(adDefaultStream).Value

Recordset

Use the Recordset object to issue Structured Query Language (SQL) SELECT commands in folders. For example:
Dim Conn as New ADODB.Connection
Conn.Provider = "ExOLEDB.DataSource"
Conn.Open RootFolderURL
Dim Rs as New ADODB.Recordset
Set Rs.ActiveConnection = Conn
"select ""DAV:displayname"" " _
& "from scope('shallow traversal of ""URL""')" _
& "Where ""DAV:ishidden"" = False"

Stream

Use the ADO Stream object to access an item's stream. For example:
Dim Stm As ADODB.Stream
Dim Rec as New ADODB.Record
Dim Conn as New ADODB.Connection
Conn.Provider = "ExOLEDB.DataSource"
Conn.Open Url
Rec.Open Url, Conn
Set Stm = Rec.Fields(adDefaultStream).Value
' Or, alternately
Dim Stm2 as New ADODB.Stream
Stm2.Open Rec, adModeRead, adOpenStreamFromRecord

Connection

Use the ADO Connection object to bind to a particular public or private store, handle transactions, and share across Record and Recordset objects to avoid continually rebinding to stores. For example:
Dim Conn as New ADODB.Connection
Conn.Provider = "ExOLEDB.DataSource"
Conn.Open RootFolderURL
Conn.BeginTrans
  Rec.Open ItemURL, Conn, adModeReadWrite
..' ..
Conn.CommitTrans
Placing Connection object references in ASP Session or Application objects and reusing this connection from one ASP page to another is ideal for optimal server-side performance.

Fields/Field

Use the ADO Fields collection and the ADO Field object to access an item's properties. For example:
Dim Rec as New ADODB.Record
Dim Conn as New ADODB.Connection
Conn.Provider = "ExOLEDB.DataSource"
Conn.Open Url
Dim Flds as ADODB.Fields
Dim Fld as ADODB.Field
Rec.Open Url, Conn, adModeReadWrite
Set Flds = Rec.Fields
For Each Fld in Flds
  '...
Next Fld
...

Each of the following CDO objects provides an ADO Fields collection on its default interface, allowing you to access Web Storage System item properties directly, as if the object was an ADO Record or Recordset object:

Addressee

Appointment

BodyPart

Configuration

Exception

Folder

Item

Message

Person

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


WebDAV Access

Items in the Web Storage System can be accessed remotely by using the WebDAV protocol, defined in RFC 2518. This protocol extends the HTTP 1.1 protocol, defined by RFC 2616, to provide additional methods and capabilities. For example, it provides a means to access not only an item's contents but also an extensible set of associated properties. The protocol also defines methods used to move, copy, delete, and make collections of items. The encoding format used to transfer item properties across the network is the XML, defined in the World Wide Web Consortium Recommendation REC-xml-19980210.

Microsoft® Internet Explorer 5 provides the Microsoft XML (MSXML) Component Object Model (COM) component, a powerful XML parser and set of related tools. The XMLHTTPRequest COM class integrates with MSXML COM objects to simplify the management of client-side HTTP protocol requests and responses that contain XML bodies. Response XML data can easily be cast into HTTP-formatted data by using the XSL transformation capabilities of the MSXML component.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Using the WebDAV Protocol

This section describes how to access Microsoft Web Storage System content using the WebDAV protocol.

Many of the examples in this section use an instance of the Microsoft.XMLHTTP Component Object Model (COM) class to send and receive WebDAV requests to the Web Storage System. In addition, many examples use an instance of the Microsoft.XMLDOM COM component to construct and manipulate the XML bodies that are used for WebDAV protocol requests. The XMLHTTP COM object is part of the Microsoft MSXML 2.0 or later COM component and integrates directly with the other components. For example, you can retrieve the XML body of a successful PROPFIND command directly from the XMLHTTP object as a DOMDocument object.

Use the XMLHTTP COM class only on clients. If you are creating applications on the server where the Web Storage System is located, use the Exchange OLE DB (ExOLEDB) provider.

When manually constructing the XML body of a WebDAV request, caution must be used with certain characters. Some special characters are reserved for use by XML, so they cannot be directly used in the XML text. These characters, <, &, >, ", and ' must be substituted with the following character codes, respectively: &lt;, &amp;, &gt;, &quot;, and &apos;.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Constructing WebDAV Requests with XMLDOM

This example shows how you can construct the body of a PROPFIND WebDAV request by using the MSXML 2.0 Component Object Model (COM) component. In the XMLDOM object model, you use the AppendChild method to create nodes and add them to the XML document. After the request has been constructed as an XML Document Object Model (DOM) Document, you then pass a reference to an XMLHTTP COM object and send the PROPFIND request to the server.

VBScript

<HTML>
<HEAD>
<META NAME="GENERATOR" Content="Microsoft Visual Studio 6.0">
<TITLE>PROPFIND</TITLE>
</HEAD>
<BODY>

<SCRIPT FOR=window EVENT=onload LANGUAGE=VBScript>
<!--

Set req = CreateObject("Microsoft.XMLHTTP")
Set domin = CreateObject("Microsoft.XMLDOM")
Set domback = CreateObject("Microsoft.XMLDOM")

req.Open "PROPFIND", "http://microsoft.com/public/docs/myFile.doc", False, "TheDomain\Administrator", "thepassword"

req.setRequestHeader "Content-Type", "text/xml; charset=""UTF-8"""

Set oPi = domin.createProcessingInstruction("xml", "version='1.0'")
domin.appendChild(opi)

Set PFind = Domin.CreateNode(1, "d:propfind", "DAV:")
domin.AppendChild PFind

Set DProp = Domin.CreateNode(1, "d:prop", "DAV:")
PFind.AppendChild DProp

Set Author = Domin.CreateNode(1, "O:Author", "urn:schemas-microsoft-com:office:office")
DProp.AppendChild Author
MsgBox domin.XML, ,"IN: PROPFIND"

req.Send Domin

MsgBox req.StatusText, ,"PROPFIND"
Set domback = req.ResponseXML
MsgBox domback.XML, ,"OUT: PROPFIND"
MsgBox domback.Text, ,"OUT: PROPFIND (text)"

//-->
</SCRIPT>

</BODY>
</HTML>

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


File System Access

You can access the Web Storage System using Microsoft® Windows® Explorer and Microsoft® Win32® file-system application programming interfaces (APIs) through the installable file system (IFS). Each store (there can be many on a single host) exists as a file system folder mounted under drive M on the host server. If drive M is already in use, the next available letter in the alphabet is used. The following illustration shows the Windows Explorer view of a typical server. Note the Web Storage System folders under drive M.

You can share drive M as you would any other drive. End users can use Windows Explorer or Microsoft® MS-DOS® commands at a command prompt to update items used by Web Storage System applications. You can also restrict users without permissions from editing documents and jeopardizing data integrity.

The default names for the first public and private stores are Public Folders and MBX, respectively.

When using Win32 file-system APIs, no mechanism is present to access properties for an item; you can access only each item's stream. To access item properties, you need to use an alternate mechanism, such as the WebDAV protocol, the Exchange OLE DB (ExOLEDB) provider, or MAPI.

Please note the following functionality when using IFS:

  • Any Web Storage System item moved to a different location by using IFS causes that item to loose its Web Storage System properties because the action occurs outside the Web Storage System.
  • The Web Storage System does not create GUIDs for items copied or saved into IFS.
  • You cannot access an item in IFS if that item is being used by a programmatic process, such as an application using Microsoft® ActiveX® Data Objects (ADO) or WebDAV.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


MAPI Access

MAPI can be used not only to access the items and folders within a public information store and a private store but also to access the rich set of properties stored along with each item. MAPI is used by various industry-standard e-mail clients, such as the Microsoft® Exchange client, all versions of Microsoft® Outlook® and Outlook Express, and many versions of proprietary clients, including those sold by QUALCOMM Incorporated (Eudora) and Netscape Communications Corporation. Previous versions of Exchange Server provided stores that were accessed primarily by using MAPI providers.

Exchange 2000 Server continues to provide access to MAPI clients, such as Outlook, through the Web Storage System MAPI message-store provider. MAPI clients can access mailboxes in any private store on the server transparently. MAPI clients can access only one public folder tree per server. This public folder tree is designated as the MAPI public folder tree, and is normally specified as the /public virtual root through HTTP and the "Public Folders" top-level folder through the Exchange OLE DB (ExOLEDB) provider. To access data within other public folder trees and associated public information stores, you must use the new application programming interfaces (APIs) and protocols, such as the WebDAV protocol, the ExOLEDB provider, or the file system.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Additional Web Storage System Access Protocols

The following protocols are supported, primarily for accessing private Web Storage System mailboxes:

  • Post Office Protocol version 3 (POP3). Used to access private Inbox folders. Resources in a private store are available through this reliable yet simple wire protocol. This protocol is ubiquitous in modern e-mail–client applications, such as Microsoft® Outlook® Express.
  • IMAP4. Used for rich access to private-folder hierarchies, including the Inbox folder. Resources in a private store and within various public information stores are available through this industry-standard wire protocol. Users need only an IMAP4-supporting application to access resources through this protocol.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Constructing Web Storage System URLs

The following sections outline in detail how to construct URLs for items in the Web Storage System.

The method you use to construct URLs depends upon the URL scheme, for example, whether you use the file: or http: scheme. In addition, which URL you use to address an item depends on the access protocol or component you use to access it. For example, you can use both file: and http: URLs to identify items and folders when using the server-side Microsoft® Exchange 2000 Server OLE DB Provider. You must use http: URLs when addressing items that use the WebDAV protocol.

This section consists of the following topics:

Constructing Web Storage System OLE DB URLs

The File: URL Scheme

The HTTP URL Scheme

Constructing Web Storage System HTTP URLs

Using Relative URLs

Getting the Host Domain Name

Getting Well-Known Mailbox Folder URLs

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Constructing Web Storage System OLE DB URLs

When you use the server-side Exchange OLE DB (ExOLEDB) Provider, you can use either the file: or the http: URL scheme to identify items in the Web Storage System. These URLs are applicable for use with any component that uses this provider to access items, including Microsoft® ActiveX® Data Objects (ADO) version 2.5 and URL.

The following sections discuss how to construct URLs by using these schemes:

The File: URL Scheme

The HTTP: URL Scheme

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


The File: URL Scheme

When constructing URLs using the file: scheme for use with the Exchange OLE DB (ExOLEDB) Provider, each URL has the following two forms. You use the first form to access a user's base mailbox folder. You use the second form to access items in public folder trees.

file://./backofficestorage/domain-name/MBX/user-alias/path
file://./backofficestorage/domain-name/public-folder-tree-name/path

domain-name

The fully qualified name of the domain in which the store resides, for example, "mydomain.microsoft.com". Note that this domain name does not include the name of the server itself.

public-folder-tree-name

For private mailboxes, this is always "MBX". For items stored in a public information store, this is the name of the public folder tree in which the item resides. Note that this is not the name of the public information store that houses the public folder tree.

The following table lists the default names provided by Microsoft® Exchange 2000 Server to access private mailboxes and the default public folder tree.

Default folder tree name | Description
MBX | Contains all private mailboxes.
Public Folders | Contains the default public information store installed with Exchange 2000 Server.

When you add new public information stores and associated public folder trees, you use the name of that public folder tree in the URL. To access mailboxes in additional private stores, you always use "MBX".

user-alias

The user's Exchange mailbox alias, for example, User1.

path

The folder path to the item. This path consists of a series of folder names separated by "/" characters.

The ExOLEDB Provider registers the file: OLE DB URL namespace with the OLE DB root binder. Therefore, you need not specify this provider explicitly when you use OLE DB, Microsoft® ActiveX® Data Objects (ADO), or CDO objects to access items by using the file: URL scheme.

The URLs in the following examples use the file: scheme:

file://./backofficestorage/sample.microsoft.com/public folders/reports/report1.doc
file://./backofficestorage/sample.microsoft.com/public folders/reports/schema/

file://./backofficestorage/sample.microsoft.com/MBX/User1/Inbox
file://./backofficestorage/sample.microsoft.com/MBX/User1/Calendar
file://./backofficestorage/sample.microsoft.com/MBX/User1/Drafts

file://./backofficestorage/sample.microsoft.com/application1/app1/
file://./backofficestorage/sample.microsoft.com/application1/app1/schema

The URLs in the following examples point to a user's mailbox folders (English).

Folder | URL
Calendar | file://./backofficestorage/microsoft.com/MBX/UserAlias/Calendar
Contacts | file://./backofficestorage/microsoft.com/MBX/UserAlias/Contacts
Drafts | file://./backofficestorage/microsoft.com/MBX/UserAlias/Drafts
Inbox | file://./backofficestorage/microsoft.com/MBX/UserAlias/Inbox
Journal | file://./backofficestorage/microsoft.com/MBX/UserAlias/Journal
Notes | file://./backofficestorage/microsoft.com/MBX/UserAlias/Notes
Outbox | file://./backofficestorage/microsoft.com/MBX/UserAlias/Outbox
Sent Items | file://./backofficestorage/microsoft.com/MBX/UserAlias/Sent%20Items
Tasks | file://./backofficestorage/microsoft.com/MBX/USerAlias/Tasks
Note The URLs in the preceding table are only examples; you should not construct them manually in your application. You can retrieve all the URLs in a user's localized mailbox folder by using the IMailBox Interface on a CDO Person object or by retrieving properties on the base mailbox folder, such as urn:schemas:httpmail:inbox or urn:schemas:httpmail:calendar.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


The HTTP URL Scheme

When you construct URLs by using the http: scheme for use with the Exchange OLE DB (ExOLEDB) Provider, you follow the same procedure as you would when accessing the item over the network using the HTTP protocol. The structure of the URL is as follows:

http://servername/virtual-directory/virtual-path

The following sections describe each component of the URL.

servername

The local server name. You can use the local server's fully qualified domain name, but this is not required with the ExOLEDB Provider. The Domain Name System (DNS) is not used to resolve this name into an IP address, and the network is not used to access the item. The URL serves only to uniquely identify an item in the local computer’s Web Storage System. Only URLs for items that reside in private or public information stores on the same server can be used; you cannot access items in stores on remote servers by using the ExOLEDB Provider.

virtual-directory

The Microsoft® Exchange HTTP Virtual Server virtual directory mapped to the public folder. The following table shows the default virtual directory names for all private stores and the default public folder "Public Folders."

Virtual directory name | Description
exchange | All private mailboxes in any private store are available through this virtual directory.
public | This virtual directory is mapped to the top public folder in the default public folder tree. The default public folder name is "Public Folders".

Each virtual path starts with an Exchange HTTP Virtual Server virtual directory name.

virtual-path

The virtual path to the item. The path is virtual because multiple Exchange virtual directories can exist as a hierarchy below the first Exchange virtual directory. Each virtual subdirectory can map to a non-contiguous public folder housed in any public information store. If the subfolder is not an Exchange virtual directory, the path is identical to the physical hierarchy below the public folder.

Note When you use http: URLs with the ExOLEDB Provider, you must explicitly specify the ExOLEDB Provider binder when binding the item. This provider has the programmatic identifier "ExOLEDB.DataSource". The OLE DB Provider for Microsoft OLE DB Provider for Internet Publishing (MSDAIPP) is registered as the default provider for the http: URL scheme. If you do not specify the ExOLEDB Provider, the MSDAIPP provider attempts to service the request. This provider is not supported for use with CDO for Exchange 2000 Server (CDOEX), nor should it be used in server applications that need to scale.

The URLs in the following examples use the http: scheme:

http://server.microsoft.com/public/reports/report1.doc
http://server.microsoft.com/public/reports/schema/

http://server.microsoft.com/exchange/User1/Inbox
http://server.microsoft.com/exchange/User1/Calendar
http://server.microsoft.com/exchange/User1/Drafts

http://server.microsoft.com/application1/app1/
http://server.microsoft.com/application1/app1/schema

The URLs in the following table are examples of common file: URLs for a user's mailbox folders (English).

Folder | URL
Calendar | http://server.microsoft.com/exchange/UserAlias/Calendar
Contacts | http://server.microsoft.com/exchange/UserAlias/Contacts
Drafts | http://server.microsoft.com/exchange/UserAlias/Drafts
Inbox | http://server.microsoft.com/exchange/UserAlias/Inbox
Journal | http://server.microsoft.com/exchange/UserAlias/Journal
Notes | http://server.microsoft.com/exchange/UserAlias/Notes
Outbox | http://server.microsoft.com/exchange/UserAlias/Outbox
Sent Items | http://server.microsoft.com/exchange/UserAlias/Sent%20Items
Tasks | http://server.microsoft.com/exchange/UserAlias/Tasks
Note The URLs in the preceding table are only examples; you should not construct them manually in your application. You can retrieve all the URLs in a user's localized mailbox folder by using the IMailbox interface on a CDO Person object or by retrieving properties, such as urn:schemas:httpmail:inbox or urn:schemas:httpmail:calendar, on the base mailbox folder.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Constructing Web Storage System HTTP URLs

When you construct URLs by using the http: scheme, you follow the same procedure as when you identify a resource accessible through the HTTP protocol. The structure of the URL is:

http://servername/virtual-directory/virtual-path

servername

The Web server name. This name must resolve to the IP address of the host through what mechanism is provided, for example Domain Name System (DNS), Microsoft® Windows® Internet Naming Service (WINS), LMHOSTS file, etc.

virtual-directory

The Microsoft® Exchange HTTP Virtual Server virtual directory mapped to the public folder. The following table shows the default virtual directory names for all private stores and the default public folder "Public Folders".

virtual-path

The virtual path to the item. The path is virtual because multiple Exchange virtual directories can exist as a hierarchy below the first Exchange virtual directory. Each virtual subdirectory can map to a non-contiguous public folder housed in any public information store. If the subfolder is not an Exchange virtual directory, the path is identical to the physical hierarchy below the public folder.

Virtual directory name | Description
exchange | All private mailboxes in any private store are available through this virtual directory.
public | This virtual directory is mapped to the top public folder in the default public folder tree. The default public folder name is "Public Folders".

Each virtual path starts with an Exchange Virtual Server virtual directory.

The URLS in the following examples use the http: scheme:
http://server.microsoft.com/public/reports/report1.doc
http://server.microsoft.com/public/reports/schema/

http://server.microsoft.com/exchange/User1/Inbox
http://server.microsoft.com/exchange/User1/Calendar
http://server.microsoft.com/exchange/User1/Drafts

http://server.microsoft.com/application1/app1/
http://server.microsoft.com/application1/app1/schema

The URLS in the following table are examples of common http: URLs for a user's mailbox folders (English).
Folder | URL
Calendar | http://server.microsoft.com/exchange/UserAlias/Calendar
Contacts | http://server.microsoft.com/exchange/UserAlias/Contacts
Drafts | http://server.microsoft.com/exchange/UserAlias/Drafts
Inbox | http://server.microsoft.com/exchange/UserAlias/Inbox
Journal | http://server.microsoft.com/exchange/UserAlias/Journal
Notes | http://server.microsoft.com/exchange/UserAlias/Notes
Outbox | http://server.microsoft.com/exchange/UserAlias/Outbox
Sent Items | http://server.microsoft.com/exchange/UserAlias/Sent%20Items
Tasks | http://server.microsoft.com/exchange/UserAlias/Tasks
Note The URLs in the previous table are only examples; you should not construct them manually in your application. You can retrieve all the URLs in a user's localized mailbox folder by using the IMailBox Interface on a CDO Person object or by retrieving properties, such as urn:schemas:httpmail:inbox or urn:schemas:httpmail:calendar, on the base mailbox folder.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Using Relative URLs

When using the Exchange OLE DB (ExOLEDB) provider, all operations on items in a particular public information store or mailbox store run in an OLE DB session. After this session has been established with a particular store, you can refer to items in that store by using relative URLs. These operations are called scoped operations, the scope being the folder tree residing in that particular store. With http: URL, the relative URLs must include the entire path, starting from the root virtual directory. With file: URLs, the path starts with the first folder below the top-level folder. You can also use relative URLs when you construct Structured Query Language (SQL) queries for folders in a store.

With Microsoft® ActiveX® Data Objects (ADO), the OLE DB session object that houses the current session information is wrapped using an instance of an ADO Connection object. After you have established the session (Connection) to a particular store, you can then dispense with generating the fully qualified URL for items in that store when you use ADO Record and Recordset objects.

For example, the following functions demonstrate this functionality in a public information store:

  • The getConnection function returns an ADO Connection object that is connected to a particular store. To create the Connection using the file: URL scheme, you need only specify the name of the top-level public folder within that store. The fully qualified domain name is retrieved using the ADSystemInfo object. This is all the information you need to connect to a public folder tree in a public information store. However, for mailboxes, you also need the user's alias.
  • The getRecord_ro function returns a read-only ADO Record object bound to the item specified using a relative URL in a particular store. The caller can pass either an open Connection object or the name of the top-level public folder. In the latter case, the function uses the getConnection function internally to retrieve a Connection to the store identified by the specified top-level public folder.
  • The getRecord_rw function returns a read-write ADO Record object bound to the item specified using a relative URL. The caller can pass either an open Connection object or the name of the top-level public folder. In the latter case, it uses the getConnection function internally to retrieve a Connection to the store identified by the specified top-level public folder.

VBScript

Const adModeReadWrite = 3

Function getConnection( relUrl )

 If not VarType(relUrl) = vbString Then
  Err.Raise &H80070057 ' E_INVALIDARG
 End If

 Dim Info
 Dim Domain
 Dim Url
 Set InfoNT = CreateObject("WinNTSystemInfo")
 Set Info   = CreateObject("ADSystemInfo")

 Dim Conn
 Set Conn = CreateObject("ADODB.Connection")

 Url = "http://" & lcase(InfoNT.ComputerName) & "." & Info.DomainDNSName & relUrl
 wscript.echo Url
 Conn.Provider = "ExOLEDB.DataSource"
 Conn.Open Url

 Set getConnection = Conn
End Function

' getRecord_ro
'
'   vSource is either the name of a top-level public folder or
'            an open ADO Connection object.
'   RelURI is the relative URI to an item within the store
'
Function getRecord_ro( relURL, Conn )

 If not VarType(relUrl) = vbString And ( (TypeName(Conn) = "Connection") Or (TypeName(Conn) = "Nothing") ) Then
  Err.Raise &H80070057 ' E_INVALIDARG
 End If

 Dim Rec
 Set Rec = CreateObject("ADODB.Record")

 If Not TypeName(vSource) = "Connection" Then
  Set Conn = getConnection(relUrl)
 End If

 Rec.Open relURL, Conn

 Set getRecord_ro = Rec

End Function

' getRecord_rw
'   vSource is either the name of a top-level public folder or
'           an open ADO Connection object.
'   RelURI is the relative URI to an item within the store
'
Function getRecord_rw(relURL, Conn )

 If not VarType(relUrl) = vbString And ( (TypeName(Conn) = "Connection") Or (TypeName(Conn) = "Nothing") ) Then
  Err.Raise &H80070057 ' E_INVALIDARG
 End If

 Dim Rec
 Set Rec = CreateObject("ADODB.Record")

 If Not TypeName(Conn) = "Connection" Then
  Set Conn = getConnection(relUrl)
 End If

 Rec.Open relURL, Conn, adModeReadWrite
 Set getRecord_rw = Rec

End Function

Assume that you have a folder called "test1" below your Public Folders top-level folder in a public information store, and an item in "test1" called "item1.txt". To access the folder and the item, you could use these functions in the following way:

VBScript

Const adDefaultStream = -1

Dim Conn
Dim Rec
Dim Rec2

Set Conn = getConnection("/apps")
Set Rec  = getRecord_rw("/apps/test1/Schema",    Conn)
Set Rec2 = getRecord_ro("/apps/test1/item1.txt", Conn)

WScript.Echo Rec.Fields("DAV:href")
Wscript.Echo Rec.Fields("DAV:contentclass")

wscript.echo

WScript.Echo Rec2.Fields("DAV:href")
wscript.echo Rec2.fields("DAV:contentclass")
Set Stm = Rec2.Fields(adDefaultStream).Value
stm.charset = "us-ascii"
WScript.Echo Stm.readText

Note that the string "Public Folders" does not appear in the relative URL. This name is used to connect to the appropriate public folder tree. After you have connected, you no longer need to specify this information in your relative URLs.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Getting the Host Domain Name

When you use the file: URL scheme to identify the location of items in the Web Storage System, you need the fully qualified domain name of the host. The following programming task demonstrates how to retrieve the domain name of the host on which the code is running.

To increase performance, you should retrieve this name once, store it, and then use the stored version when constructing URLs. For example, if you are writing an Active Server Pages (ASP) application, retrieve the domain name and then place this information in the ASP Application collection for subsequent use by other scripts.

VBScript

Function GetDomainName()

 Dim Info
 Set Info = CreateObject("AdSystemInfo")
 GetDomainName = Info.DomainDNSName

End Function

Function GetComputerName()

 Dim InfoNT
 Set InfoNT = CreateObject("WinNTSystemInfo")
 GetComputerName = lcase(InfoNT.ComputerName)

End Function

Function GetForestDNSName()

 Dim Info
 Set Info = CreateObject("AdSystemInfo")
 GetForestDNSName = Info.ForestDNSName

End Function

Visual Basic

Function GetDomainName()

 Dim Info As New ADSystemInfo
 GetDomainName = Info.DomainDNSName

End Function

Function GetComputerName()

 Dim InfoNT As New WinNTSystemInfo
 GetComputerName = LCase(InfoNT.ComputerName)

End Function

Function GetForestDNSName()

 Dim Info As New ADSystemInfo
 GetForestDNSName = Info.ForestDNSName

End Function

Visual C++

#define _WIN32_WINNT 0x0500
#define _UNICODE
#define UNICODE

#include <windows.h>
#include <comdef.h>
#define BUF_SIZE 4096

bstr_t getHostDomainName() {

   HRESULT hr     = S_OK;
   BSTR   domainName;
   DWORD dwSize  = 0;
   wchar_t* pBuf = new wchar_t[BUF_SIZE];
   if(pBuf == NULL)
      _com_issue_error(E_OUTOFMEMORY);

   if(!GetComputerNameEx((COMPUTER_NAME_FORMAT)ComputerNameDnsDomain,
                     pBuf,
                     &dwSize)) {
      if(GetLastError() == ERROR_MORE_DATA) {
         delete [] pBuf;
         pBuf = new wchar_t[dwSize+1];
         if(pBuf == NULL)
            _com_issue_error(E_OUTOFMEMORY);

         if(!GetComputerNameEx((COMPUTER_NAME_FORMAT)ComputerNameDnsDomain, pBuf, &dwSize) ) {
            hr =   HRESULT_FROM_WIN32(GetLastError());
            delete [] pBuf;
            pBuf    = NULL;
            _com_issue_error(hr);
         }
      }
      else
         _com_issue_error(HRESULT_FROM_WIN32(GetLastError()));
   }

   domainName = SysAllocString(pBuf);
   delete [] pBuf;

   return bstr_t(domainName, false);
}

#define _WIN32_WINNT 0x0500
#define _UNICODE
#define UNICODE

#include <windows.h>
#include <comdef.h>
#define BUF_SIZE 4096

bstr_t getHostName() {

   HRESULT hr         = S_OK;
   BSTR   hostName;
   DWORD   dwSize      = 0;
   wchar_t* pBuf = new wchar_t[BUF_SIZE];
   if(pBuf == NULL)
      _com_issue_error(E_OUTOFMEMORY);

   if(!GetComputerNameEx((COMPUTER_NAME_FORMAT)ComputerNameDnsHostname,
                     pBuf,
                     &dwSize)) {
      if(GetLastError() == ERROR_MORE_DATA) {
         delete [] pBuf;
         pBuf = new wchar_t[dwSize+1];
         if(pBuf == NULL)
            _com_issue_error(E_OUTOFMEMORY);

         if(!GetComputerNameEx((COMPUTER_NAME_FORMAT)ComputerNameDnsHostname, pBuf, &dwSize) ) {
            hr =   HRESULT_FROM_WIN32(GetLastError());
            delete [] pBuf;
            pBuf    = NULL;
            _com_issue_error(hr);
         }
      }
      else
         _com_issue_error(HRESULT_FROM_WIN32(GetLastError()));
   }

   hostName = SysAllocString(pBuf);
   delete [] pBuf;

   return bstr_t(hostName, false);
}

#define _WIN32_WINNT 0x0500
#define _UNICODE
#define UNICODE

#include <windows.h>
#include <comdef.h>
#define BUF_SIZE 4096

bstr_t getFQDName() {

   HRESULT hr         = S_OK;
   BSTR   fqdname;
   DWORD   dwSize      = 0;
   wchar_t* pBuf = new wchar_t[BUF_SIZE];
   if(pBuf == NULL)
      _com_issue_error(E_OUTOFMEMORY);

   if(!GetComputerNameEx((COMPUTER_NAME_FORMAT)ComputerNameDnsFullyQualified,
                     pBuf,
                     &dwSize)) {
      if(GetLastError() == ERROR_MORE_DATA) {
         delete [] pBuf;
         pBuf = new wchar_t[dwSize+1];
         if(pBuf == NULL)
            _com_issue_error(E_OUTOFMEMORY);

         if(!GetComputerNameEx((COMPUTER_NAME_FORMAT)ComputerNameDnsFullyQualified, pBuf, &dwSize) ) {
            hr =   HRESULT_FROM_WIN32(GetLastError());
            delete [] pBuf;
            pBuf    = NULL;
            _com_issue_error(hr);
         }
      }
      else
         _com_issue_error(HRESULT_FROM_WIN32(GetLastError()));
   }

   fqdname = SysAllocString(pBuf);
   delete [] pBuf;

   return bstr_t(fqdname, false);
}

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Getting Well-Known Mailbox Folder URLs

Each user's mailbox folder has a set of properties that you can use to retrieve URLs for well-known subfolders such as Inbox, Calendar, Drafts, and Tasks. Additionally, you can retrieve the Microsoft® Exchange mail submission Uniform Resource Identifier (URI) that is used to send messages through WebDAV or the Exchange OLE DB (ExOLEDB) provider. The returned URLs are localized into the language that is used by the client.

The following table lists the properties that return these URLs and that are retrieved from a user’s root mailbox folder.

Property | Well-known folder (English)
urn:schemas:httpmail:calendar | Calendar
urn:schemas:httpmail:contacts | Contacts
urn:schemas:httpmail:deleteditems | Deleted Items
urn:schemas:httpmail:drafts | Drafts
urn:schemas:httpmail:inbox | Inbox
urn:schemas:httpmail:journal | Journal
urn:schemas:httpmail:notes | Notes
urn:schemas:httpmail:outbox | Outbox
urn:schemas:httpmail:sentitems | Sent Items
urn:schemas:httpmail:tasks | Tasks
urn:schemas:httpmail:sendmsg | Exchange Mail Submission URI
urn:schemas:httpmail:msgfolderroot | Mailbox folder (root)

To access these properties:

  1. Bind to the user’s root mailbox folder. You can either request the server and username from the client to construct this initial URL or search Microsoft® Active Directory™ for the user's homeMDB attribute. From the value of this attribute, you can get the server on which the user's private mailbox is stored.
  2. Use the values of these properties to bind to these folders in a mailbox folder.

VBScript

<Job id="printMailboxURLs">

<reference object="ADODB.Record"/>
<reference object="CDO.Message"/>

<script language="VBScript">

userName   = WScript.Arguments.Item(0)

set info   = createobject("adsysteminfo")
set infoNT = CreateObject("WinNTSystemInfo")

urls = getStdWellKnownMailboxURLs("http://" & lcase(infoNT.ComputerName) & "." & _
                                 Info.domaindnsname & "/exchange/" & userName, _
                                 "ExOLEDB.DataSource")

wscript.echo "Well-known mailbox file: URLs for local mailbox: " & userName
wscript.echo "========================================"

For i = LBound(urls) to UBound(urls) step 2
 wscript.stdout.write urls(i)
 if Len(urls(i)) > 7 then
  wscript.stdout.write vbTab
 else
  wscript.stdout.write vbTab & vbTab
 end if
 wscript.stdout.write urls(i+1) & vbCrLf
next

Function getStdWellKnownMailboxURLs( mailboxFolderURL, provider )

 If Not TypeName(mailboxFolderURL) = "String" Then
  Err.Raise  &H80070057 ' E_INVALIDARG
 End If

 Dim Rec
 Set Rec = CreateObject("ADODB.Record")
 Dim Conn
 Set Conn = CreateObject("ADODB.Connection")
 Conn.Provider =  provider
 Conn.Open mailboxFolderURL

 Rec.Open mailboxFolderURL, Conn
 Set Flds = Rec.Fields

 ' The constants used here are defined in the CDOEx.dll type library.
 ' They are imported using the <reference> element above.

 getStdWellKnownMailboxURLs = Array( _
              "Calendar" , Flds(cdoCalendarFolderURL), _
              "Contacts" , Flds(cdoContactFolderURL), _
              "DeletedIt", Flds(cdoDeletedItems), _
              "Inbox"    , Flds(cdoInbox), _
              "Journal"  , Flds(cdoJournal), _
              "MsgRoot"  , Flds(cdoMsgFolderRoot), _
              "Notes"    , Flds(cdoNotes), _
              "Outbox"   , Flds(cdoOutbox), _
              "SendMsg"  , Flds(cdoSendMsg), _
              "SendItems", Flds(cdoSentItems), _
              "Tasks"    , Flds(cdoTasks) )

End Function

</script>

</Job>

C++

#import <msado15.dll> no_namespace
#import <c:\program files\common files\microsoft shared\cdo\cdoex.dll> no_namespace
#include <iostream.h>

void printMailboxFolders(bstr_t mailtoUrl) {

   IMailboxPtr iMbx;
   try {
      iMbx = getIMailbox(mailtoUrl);
   }
   catch(_com_error e) {
      throw e;
   }

   cout << "BaseFolder: " << iMbx->BaseFolder << endl;
   cout << "Inbox: "      << iMbx->Inbox << endl;
   cout << "Calendar: "   << iMbx->Calendar << endl;
   cout << "Drafts: "     << iMbx->Drafts << endl;

   //...

   IDataSourcePtr iDsrc;
   iDsrc = iMbx;
   cout << iDsrc->SourceURL << endl;
   _RecordPtr Rec(__uuidof(Record));
   _ConnectionPtr Conn(__uuidof(Connection));
   Conn->Provider = "ExOLEDB.DataSource";
   bstr_t sSendMsgUrl;
   try {
      Conn->Open(iMbx->BaseFolder, bstr_t(),bstr_t(), -1);
      Rec->Open(iMbx->BaseFolder, variant_t((IDispatch*)Conn, true), adModeRead, adFailIfNotExists, adOpenRecordUnspecified, bstr_t(), bstr_t());
      sSendMsgUrl = bstr_t(Rec->Fields->Item["urn:schemas:httpmail:sendmsg"]->Value);
   }
   catch(_com_error e) {
      cout << "Error binding to user's base mailbox folder. " << endl;
      throw e;
   }
   cout << "Mail Submission URI: " << sSendMsgUrl << endl;

}

IMailboxPtr getIMailbox( bstr_t mailtoUrl) {

   IPersonPtr Per(__uuidof(Person));
   IDataSourcePtr Dsrc;
   Dsrc = Per;
   try {
      Dsrc->Open(mailtoUrl, NULL, adModeRead, adFailIfNotExists, adOpenRecordUnspecified, bstr_t(),bstr_t());
   }
   catch(_com_error e) {
      throw e;
   }

   return Per;
}

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Web Storage System Item Properties

Using the Web Storage System, you can easily store any number of properties (also called fields) along with each item. You can access the value of each property, and you can search and group items having properties that match certain conditions.

Any number of properties can be stored with each item, and the set of properties for each item can be different. Unlike with a relational database, you do not need to add a column to a table to set an item property.

Web Storage System item properties have names made up of a namespace and a local name. The namespace is a unique string that acts as a scope for the name. Using a namespace is preferred and guarantees that each property with a shared local name is unique within the store. Namespaces are defined using the Uniform Resource Identifier (URI) syntax. Examples of URI values used are urn:schemas:httpmail: and http://schemas.microsoft.com/exchange/.

This section consists of the following topics:

Namespaces and Property Names

Default Web Storage System Namespaces

Custom Properties

Property Names and the Exchange OLE DB Provider

Property Names and WebDAV

Property Names and XML

Property Data Types

The Item Default Stream Property

Automatic Property Promotion from the Stream

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Namespaces and Property Names

It is recommended that property names for Web Storage System items be composed of a Uniform Resource Identifier (URI) and a local name. The URI portion of the property name ensures that it is globally unique and unambiguous. Two properties with the same local name can therefore be differentiated using namespaces.

For example, one application might use a property called state. In one case, "state" may refer to a country, and in another case it may refer to a state of some document in a process. Both properties are made unambiguous for an item by adding a URI prefix to the property names, as in the following example:

urn:schemas-domain1-tld:state
urn:schemas-domain2-tld:state

The two names are broken down into the parts shown in the following tables.

urn:schemas-domain1-tld:state

URI component | Value
Namespace URI | urn:schemas-domain1-tld:
Property name (local part) | state
Full name | urn:schemas-domain1-tld:state

urn:schemas-domain2-tld:state

URI component | Value
Namespace URI | urn:schemas-domain2-tld:
Property name (local part) | state
Full name | urn:schemas-domain2-tld:state

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Default Web Storage System Namespaces

The Web Storage System defines and reserves the namespaces listed in the following table. These namespaces can be used in property names.

Namespace | Description
DAV: | Properties defined for the WebDAV protocol, including properties for general data access (such as DAV:href) and for determining hierarchical information (such as DAV:isfolder).
http://schemas.microsoft.com/exchange/ | Properties specific to Microsoft® Exchange 2000 Server and Web Storage System.
http://schemas.microsoft.com/exchange/events/ | Properties used to create event sink binding items.
urn:schemas-microsoft-com:office:forms | Properties used to register HTML forms in the Web Storage System.
http://schemas.microsoft.com/exchange/security/ | Properties specific to security features for items in the Web Storage System.
urn:schemas:microsoft-com:datatypes: | Definitions for data types used when creating schema items.
urn:schemas:microsoft-com:exch-data: | Definitions for Exchange-specific data types used for Web Storage System properties.
urn:schemas:microsoft-com:xml-data: | Definitions for XML namespaces that incorporate dynamic data typing and binding.
urn:schemas:microsoft-com:office:office | Properties specific to Microsoft® Office files.
urn:schemas:calendar: | Properties used for calendaring. The following properties are also available for CDO calendar objects: Appointment, CalendarMessage, CalendarPart, Exception, RecurrencePattern, and Addressee.
urn:schemas:contacts: | Properties for managing contacts. Several properties are also available for the CDO Person object.
urn:schemas:httpmail: | Fields used to create and process the body of a message. For fields in the header of a message, use the mail header namespace.
urn:schemas:mailheader: | Standard mail header properties for messages. Several properties are also available for the CDO Message object.

When adding your own properties to items, you use your own namespace Uniform Resource Identifier (URI) in the property name to make each one unique.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Custom Properties

Although the Web Storage System provides a large number of predefined properties used for standard applications, you can store any number of additional properties along with each item; these are called custom properties. Each item can have a completely different set of custom properties that you define.

A custom property is persisted with its associated item and can be requested by name when examining the item. When you bind directly to items using the Exchange OLE DB (ExOLEDB) provider or Microsoft® ActiveX® Data Objects (ADO), or when you issue a PROPFIND command with a depth of 0 through the WebDAV protocol, the Web Storage System returns all custom properties for the item. Custom properties are not visible to a Structured Query Language (SQL) 'SELECT *' statement or a PROPFIND command for all item properties with a depth of 1 unless they are defined as part of the item's content class. Therefore, to make your properties discoverable to schema-aware applications such as the Web Storage System query processor, you must add property and content class definitions to the application folder's schema scope.

When searching for custom properties using an SQL statement, you should use the CAST element for all properties that are not of the string type. Custom properties should be cast in both the SELECT list and the WHERE clause portions of the SQL statement.

Related Topics

  • Web Storage System Schema
  • Custom Properties and MAPI

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Namespace Guidelines

When creating a name for a custom property, you should use a namespace Uniform Resource Identifier (URI) to provide scope and uniqueness for the name. The following guidelines are recommended:

  • If your company or organization has registered a domain name with InterNIC, use this name when constructing a namespace for your custom properties.
  • Make sure to use a valid URI scheme for your namespaces. This guarantees that no problems are encountered when transmitting these custom properties through the WebDAV protocol.
  • Avoid using a namespace scheme that denotes standard properties, such as urn:content-classes:, urn:schemas:, and so on. Make sure you incorporate your domain name in the namespace. For example:
    urn:schemas-domain-tld:
http://schemas.domain.tld/myschema/

    where tld denotes the top-level domain.

  • Define custom properties as part of an application schema. This provides a mechanism for discoverability as well as the ability to return custom properties when a SELECT * statement is executed on a folder containing resources that use custom properties. For more information, see Web Storage System Schema.
  • If your company or organization does not have a registered domain name, try to generate a namespace that will render your property names as unique as possible. One way to guarantee this is to use a globally unique identifier (GUID) you generate on one of your computers in the namespace, as in the following:
    urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/

    This mechanism, although guaranteed to render the namespace unique, is not simple to read, and it may be difficult to present to users in Microsoft® Outlook®; or Web forms.

  • Make sure you understand how fully qualified names are constructed when setting custom properties using the WebDAV protocol. For example, when constructing the XML code to set custom properties, omitting either the colon (:) or the forward slash (/) at the end of the XML namespace reference causes the number sign (#) to be used as a separator. If you later request the property by concatenating the property to the namespace with the appropriate separator character, the Exchange OLE DB (ExOLEDB) provider returns an error indicating that the property is not defined. Note that you can always verify the name of a property by requesting all properties through a WebDAV PROPFIND command or by binding the associated item directly by using Microsoft® ActiveX® Data Objects (ADO) or OLE DB.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Custom Properties and MAPI

Custom properties that you set by using either the WebDAV protocol or the Exchange OLE DB (ExOLEDB) provider are available for use by MAPI clients, including MAPI Microsoft® Outlook® forms. All custom properties are accessible on items as named properties within the PS_PUBLIC_STRINGS MAPI namespace.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Property Names and the Exchange OLE DB Provider

When you access item properties using the server-side Exchange OLE DB (ExOLEDB) provider, you construct the property names by combining the namespace Uniform Resource Identifier (URI) and the local name, as shown in the following table.

Namespace URI | Local name | Full name
DAV: | contentclass | DAV:contentclass
urn:schemas:mailheader: | to | urn:schemas:mailheader:to
http://schemas.microsoft.com/ exchange/security/ | descriptor | http://schemas.microsoft.com/ exchange/security/descriptor
urn:schemas-microsoft- com:office:office | Author | urn:schemas-microsoft- com:office:office#Author

When combining the namespace URI and the local name to form the full name, the following rules are used to determine the separation character:

  1. If the namespace ends with the character '/', ':', or '?', the two parts of the name are simply joined; for example, "DAV:" + "contentclass" gives "DAV:contentclass".
  2. Otherwise, the "#" character is appended to the namespace URI and is used to separate the namespace URI from local name. For example, "urn:schemas-microsoft-com:office:office" + "Author" gives "urn:schemas-microsoft-com:office:office#Author". Adding "urn:schemas-domain-tld#" + "casenumber" yields "urn:schemas-domain-tld##casenumber".

The reverse of these rules are used to separate a namespace from a local name when transmitting properties using the WebDAV protocol.

Full names are used regardless of whether you are requesting access to the property through a Structured Query Language (SQL) statement, a Microsoft® ActiveX® Data Objects (ADO) Fields collection, or an OLE DB IRow or IRowset interface.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Property Names and WebDAV

When you access item properties using the WebDAV protocol, the property names are represented as namespace-scoped XML elements complying with the Namespaces in XML Recommendation. For example, a property accessible through the Exchange OLE DB (ExOLEDB) provider with the name "DAV:contentclass" is represented through WebDAV as:

<a:contentclass xmlns:a="DAV:">[value]</a:contentclass>

The prefix "a" in this example acts only as a placeholder for the Uniform Resource Identifier (URI) "DAV:" and is not part of the property name.

The following typical response to the PROPFIND WebDAV command:

PROPFIND /path/resource.eml HTTP/1.1
Content-Type: text/xml
Content-Length: XXX

<?xml version="1.0" encoding="UTF-8"?>
<d:propfind xmlns:d="DAV:">
 <d:prop><d:displayname/></d:prop>
 <d:prop><d:getcontentlength/></d:prop>
 <d:prop><d:resourcetype/></d:prop>
 <d:prop><d:iscollection/></d:prop>
</d:propfind>

might look like the following:

<?xml version='1.0'?>
<a:multistatus
  xmlns:a="DAV:"
  xmlns:b="urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/"
>
<a:response>
<a:href>http://microsoft.com/path/resource.eml</a:href>
<a:propstat>
  <a:status>HTTP/1.1 OK</a:status>
  <a:prop>
    <a:displayname>resource.eml</a:displayname>
    <a:getcontentlength>367</a:getcontentlength>
    <a:resourcetype><a:collection/></a:resourcetype>
    <a:iscollection b:dt="boolean">0</a:iscollection>
  </a:prop>
</a:propstat>

In this example, the properties "DAV:displayname", "DAV:getcontentlength", "DAV:resourcetype", and "DAV:iscollection" were requested for the item at the URL "http://microsoft.com/path/resource.eml". Note that the prefixes ("a" and "d") used as placeholders for the "DAV:" URI are different in the two XML strings. The following table shows full names and example-scoped XML elements side by side.

Note The prefix used as a placeholder for the namespace URI is random and always refers to a namespace URI.
Full name | Example-scoped XML element
DAV:resourcetype | <a:resourcetype xmlns:a="DAV:"/>
DAV:iscollection | <b:iscollection xmlns:b="DAV:"/>
DAV:getcontentlength | <c:getcontentlength xmlns:c:="DAV:"/>
DAV:iscollection | <d:iscollection xmlns:d="DAV:"/>

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Property Names and XML

When an application accesses a Web Storage System property by using the WebDAV protocol, the property name, when placed in an XML stream, is disassembled into its namespace and name parts. When the property name is taken out of the XML stream, it is reassembled and then saved to the item in the Web Storage System. This happens transparently within the WebDAV service itself. The following rules are used to identify the namespace and the name portions of a fully qualified property name when disassembling it for transport using HTTP.

  • Valid URL and URN schema-separator characters, which delimit namespace names from property names, are as follows: forward slash (/), colon (:), semicolon (;), number sign (#), question mark (?).

    When disassembling a property name into a namespace Uniform Resource Identifier (URI) and a local name, the string is scanned from right to left until one of the characters listed in the preceding paragraph is found.

  • If the separator character is the number sign (#), the namespace is the entire string to the left of the character. The property name is the string to the right of it.
  • If the separator is not the number sign, the namespace name is the entire string to the left of the property name. The property name is the string to the right of the separator character.

The following table shows how a fully qualified property name is disassembled into its parts.

Namespace | Name | Full name
urn:schemas-microsoft-com: | prop1 | urn:schemas-microsoft-com:prop1
http://microsoft.com/schema | prop2 | http://microsoft.com/schema#prop2
http://exchange.microsoft.com/schema/ | prop3 | http://exchange.microsoft.com/schema/prop3
urn:property# | prop4 | urn:property##prop4
urn:property? | prop5 | urn:property?prop5

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Property Data Types

A rich set of single-value and multivalued data types is provided for item properties in the Web Storage System. The following table lists these types, using the XML-data representation for each one. The second table lists the mappings between these data types and the types presented using OLE DB and MAPI.

Types ( XML) | Description
Boolean | A Boolean value, either True or False. In an XML string, this value is either "1" for True or "0" for False.
i2, mv.i2 | 2-byte integer.
int, mv.int | 4-byte integer.
i8, mv.i8 | 8-byte integer.
dateTime.tz, mv.dateTime.tz | Date and time.
r4, mv.r4 | 4-byte floating-point number.
fixed.14.4, mv.fixed.14.4 | Fixed floating-point number.
float, mv.float | Floating-point number.
uri | Uniform Resource Identifier in string format
uuid, mv.uuid | GUID in string format.
string, mv.string | 2-byte character string (Unicode).
bin.base64 mv.bin.base64 | Binary data (base 64-encoded).

Data Type Mappings

The following table lists the mappings between types in Exchange OLE DB (ExOLEDB) provider, MAPI, and XML (WebDAV).

XML-data type | OLE DB type | MAPI type
boolean | DBTYPE_BOOL | PT_BOOLEAN
i2 mv.i2 | DBTYPE_I2 DBTYPE_ARRAY | DBTYPE_I2 | PT_I2 PT_MV_I2
int mv.int | DBTYPE_I4 DBTYPE_ARRAY | DBTYPE_I4 | PT_LONG PT_MV_LONG
i8 mv.i8 | DBTYPE_I8 DBTYPE_ARRAY | DBTYPE_I8 | PT_I8 PT_MV_I8
dateTime.tz mv.dateTime.tz | DBTYPE_FILETIME DBTYPE_ARRAY | DBTYPE_FILETIME | PT_SYSTIME PT_MV_SYSTIME
dateTime.tz mv.dateTime.tz | DBTYPE_FILETIME DBTYPE_ARRAY | DBTYPE_FILETIME | PT_APPTIME PT_MV_APPTIME
r4 mv.r4 | DBTYPE_R4 DBTYPE_ARRAY | DBTYPE_R4 | PT_R4 PT_MV_R4
fixed.14.4 mv.fixed.14.4 | DBTYPE_CY DBTYPE_ARRAY | DBTYPE_CY | PT_CURRENCY PT_MV_CURRENCY
float mv.float | DBTYPE_DOUBLE DBTYPE_ARRAY | DBTYPE_DOUBLE | PT_DOUBLE PT_MV_DOUBLE
uuid mv.uuid | DBTYPE_GUID DBTYPE_ARRAY | DBTYPE_GUID | PT_CLSID PT_MV_CLSID
string mv.string | DBTYPE_WSTR DBTYPE_ARRAY | DBTYPE_WSTR | PT_UNICODE PT_MV_UNICODE
string mv.string | DBTYPE_STR DBTYPE_ARRAY | DBTYPE_STR | PT_STRING8 PT_MV_STRING8
bin.base64 mv.bin.base64 | DBTYPE_BYTES DBTYPE_ARRAY | DBTYPE_BYTES | PT_BINARY PT_MV_BINARY
Not supported | DBTYPE_ERROR | PT_ERROR
Not supported | DBTYPE_NULL | PT_NULL
Not supported | DBTYPE_IUNKNOWN | PT_OBJECT
Not supported | Not supported | PT_UNSPECIFIED

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


The Item Default Stream Property

Each item in the Web Storage System that is not a collection has a special property called the default stream. This property contains any sequence of characters or bytes of any length, just like a file on the file system. At first glance, the stream for an item might appear to be equivalent to another property whose type is text or binary. The primary differences are as follows:

  • The default stream for an item is always available using the same name or index, regardless of the item.
  • The stream can contain a sequence of characters or bytes of any length. Regular text or binary properties have limited size. Text properties can be up to 50 KB.
  • Only the item's stream is available through the Microsoft® Win32® file system application programming interfaces (APIs). In this way, item default streams are the same as the contents of a file on the file system.

When using Microsoft® ActiveX® Data Objects (ADO) or CDO, you access the item's stream by requesting the property with the value adDefaultStream in the Fields collection. The returned Field object contains a reference to an ADO Stream object (_Stream interface). With OLE DB, the property is requested using the DBGUID_DEFAULTSTREAM flag. The stream is accessed using the returned IStream interface reference. The ADO Stream object differentiates between binary and text streams. No differentiation exists when using the raw IStream interface.

No inherent relationship exists between an item's properties and its stream, with a few notable exceptions: Items that are messages and Microsoft® Office documents, both of which are handled in a special way.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Automatic Property Promotion from the Stream

The Web Storage System provides special handling called property promotion for messages and Microsoft® Office documents when their content streams are saved. Typically, when you create an item in the Web Storage System, no inherent relationship exists between the item’s properties and its stream. With messages and Office documents, however, the item stream is automatically examined as it is being saved to the store, and property values are extracted from this stream and set for the item. Note, however, that this is a one-way action; if properties are subsequently set on the item, the stream is not automatically updated.

Property promotion is triggered in one of two ways: through file extensions, or through content type when using the WebDAV protocol. A Web Storage System item saved with the one of the file name extensions listed and described in the following table has its stream content automatically examined for properties that are then promoted as fields for the item.

File name extension | Description
.eml | Denotes an RFC 822-formatted message. Typically, messages are further formatted using the Multipurpose Internet Mail Extensions (MIME). The message stream is parsed, and the value of various mail header fields such as To: and From: are added ("promoted") to the item as properties. The DAV:contentclass for the item is also set appropriately; for example, urn:content-classes:message, and urn:content-classes:calendarmessage.
.doc, .xls, .ppt and other Office extensions | Results in the item being created with DAV:contentclass set to urn:content-classes:document. For Office documents that have standard extensions such as .doc, .xls, or .ppt, document properties available within the file's standard structured storage are added as item properties.

For example, if you copy a message in a file called item.eml to the Web Storage System using the file system, the Web Storage System assumes that the file contains a message. It parses the message content stream and sets the various messaging-related fields for the item, such as urn:schemas:httpmail:subject. Similarly, if you copy a Microsoft® Word file to the Web Storage System using the file system, the Web Storage System examines the file's structured storage for standard Office properties, extracts the values, and automatically sets them for the item. For example, the Author document property value is used to set the urn:schemas-microsoft-com:office:office#Author property for the item.

When you put items in the Web Storage System using the WebDAV protocol, Office and message and application content types also trigger property promotion. For example, if you issue a PUT command and the content type of the body of the HTTP request is "message/rfc822", the Web Storage System assumes that the inbound stream is an RFC 822 (and possibly MIME)-formatted stream, parses the stream, and promotes the various messaging-related headers to properties for the item. Similarly, the content type "application/msword" triggers the promotion of the document's structured storage properties to item properties.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Collaboration Data Objects

CDO for Exchange 2000 Server (CDOEX) is a server-side collaborative component that is used in conjunction with Microsoft® ActiveX® Data Objects (ADO) 2.5 and Active Directory™ Service Interfaces (ADSI). You can use CDOEX to create Web collaboration solutions based on the Web Storage System and Microsoft® Active Directory™ service in Microsoft® Windows® 2000. Whereas OLE DB, ADO, and ADSI provide the fundamental data access mechanisms to the Web Storage System and Active Directory, CDOEX provides extended collaborative functionality that includes the creation and management of the following:

  • Folders and non-folder items
  • Messages
  • Appointments
  • Meeting request messages and responses (accept, accept tentative, decline)
  • Contacts
  • Mailboxes, recipients, and the Web Storage System folder hierarchies and settings
  • Web Storage System event-driven workflows that manage process-driven applications

In Microsoft® Exchange 2000 Server, CDOEX is available only on the same computer (or cluster) as Exchange 2000 Server itself. In addition, CDOEX can access data only in the local Exchange 2000 Server public stores and mailbox stores. It cannot directly access data residing in different Exchange 2000 Server stores.

Note The CDO for Exchange Management (CDOEXM) component of CDOEX can be used from remote servers. You can install CDOEXM along with the Exchange 2000 Server Administration tools.

This section consists of the following topics:

CDO Components

CDO and ADO

Data Sources and Binding

The Configuration Object

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


CDO Components

CDO is a set of components with which you can build rich collaborative applications on the Web Storage System platform. The following table lists the Component Object Model (COM) components that are provided with CDO, along with a brief description of each.

Component | Description
CDO for Exchange 2000 Server (CDOEX) | Provides fundamental collaboration tools for managing messages, appointments, calendar messages, and contacts.
CDO Workflow Objects for Exchange (CDOWF) | Provides tools for writing and managing workflows by using the Web Storage System.
CDO for Exchange Management (CDOEXM) | Provides tools for managing Microsoft® Exchange 2000 Server and public information stores and private stores.

CDOEX and CDO Workflow Objects for Exchange 2000 Server are installed on the same computer as Exchange 2000 Server. These components cannot be installed remotely or used directly through distributed COM (DCOM). You can use these components in Active Server Pages (ASP), COM+ server-side components, Web Storage System event sinks, advanced workflow applications, and Microsoft® Windows® services that run on Exchange 2000 Server.

You can install the CDOEXM component on separate computers and use it to manage your Exchange 2000 Server servers remotely. For example, you can use CDOEXM in MMC snap-ins and extensions; you can also create scripts by using the Windows Scripting Host and run them on remote computers. However, you can also use the CDOEXM component on the server running Exchange 2000 Server.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


CDO for Exchange 2000 Server

CDO for Exchange 2000 Server (CDOEX) provides the fundamental tools you need for building collaboration applications that use the Web Storage System and Microsoft® Active Directory™. CDOEX provides the fundamental interfaces and Component Object Model (COM) classes that are used to manage most types of items in the Web Storage System. The CDO Workflow Objects for Exchange and the CDO for Exchange Management (CDOEXM) COM components extend this core component to provide additional functionality.

By using CDOEX, you can do the following:

  • Manage items in the Web Storage System (both folders and non-folder items).
  • Create, modify, delete, send, and post messages in Internet formats.
  • Manage all aspects of calendar and appointment interchange and related messages, including the messages that contain meeting requests and that respond to meeting requests.
  • Manage appointments in a user's calendar folder or in public folders.
  • Manage contact information in a user's contacts folder, in public folders, and in Active Directory.

The following table lists the CDOEX COM classes and interfaces with a brief description of each.

CDOEX COM class | CDOEX interface | Description
Configuration | IConfiguration | Used to configure CDO objects.
Item | IItem IDataSource | Used to manage items in the Web Storage System.
Folder | IFolder IDataSource | Used to manage folder items in the Web Storage System.
Appointment | IAppointment IBodyPart IDataSource | Used to create and manage appointment items in the Web Storage System.
Person | IPerson IDataSource IMailbox IMailRecipient* IMailboxStore* | Used to create and manage user and contact information in the Web Storage System and Active Directory.
Message | IMessage IBodyPart IDataSource | Used to create, send, respond to, and manage message items in the Web Storage System.
CalendarMessage | ICalendarMessage IMessage IBodyPart IDataSource | Used to create, send, reply to, and manage messages in the Web Storage System that contain calendar-related information.
Addressee | IAddressee IDataSource | Used to resolve addresses in Active Directory and retrieve a user's free/busy status.
Attendee | IAttendee | Used to add attendees to appointments.

* Denotes an interface that is available only if the CDOEXM Objects Library is installed.

You can use the CDOEX component as a foundation upon which to build your application's COM/COM+ components. You can aggregate the CDOEX Item and Folder COM objects in your COM objects at run time, and thereby expose consistent, CDO-based implementations of the CDOEX IItem Interface and IFolder Interface to clients.

CDOEX supports various Internet Standard formats for messages, calendar information exchange, and contact information exchange, including RFC 822, Multipurpose Internet Mail Extensions (MIME), iCalendar, and vCard formats.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


CDO and ADO

CDO and Microsoft® ActiveX® Data Objects (ADO) are designed to work in conjunction with one another. Applications use ADO to navigate, search, and modify the properties of items in the Web Storage System; they use CDO to create and manage specific types of items, such as messages, contacts, appointments, messages containing meeting requests, and folders. Whereas ADO provides raw data access, CDO provides added functionality, which:

  • Handles the creation and management of various Internet standard stream formats for items such as messages, appointments, and contacts. These formats include the RFC 822 message format, the Multipurpose Internet Mail Extensions (MIME) format, the iCalendar format (for appointment exchange), and the vCard contact format. Unlike ADO objects, CDO objects automatically keep the item's stream in synchrony with the item's properties.
  • Provides business logic that makes it easier to work with the raw data in many objects in the Web Storage System and Microsoft® Active Directory™. For example, the CDO Person object alleviates the need to remember all of the various attribute names of User objects in Active Directory when performing the most routine tasks due to schema differences.
  • Encodes and decodes data into Internet standard transfer formats, such as base64 and quoted-printable.
  • Correlates meeting request responses into a master appointment in a user's calendar folder or a public folder.
  • Able to work with both protocols and content, CDO has the ability to submit an e-mail message to a local or remote SMTP/NNTP transport.

Both CDO and ADO rely directly on the Exchange OLE DB (ExOLEDB) Provider to access data residing in the Web Storage System.

Note You can use the Microsoft OLE DB Provider for Internet Publishing (MSDAIPP) with ADO to remotely access information in the Web Storage System. Using CDO for Exchange 2000 Server (CDOEX) or CDOWF with the MSDAIPP provider is not supported.

In addition, the MSDAIPP provider relies on the WinInet application programming interface (API) to manage HTTP connections. The WinInet API is not supported in middle-tier or server-side applications. Therefore, you should not use MSDAIPP in middle-tier or server-side applications.

CDO objects can also be bound to ADO objects directly; this increases performance by not requiring separate bindings to the item in a particular store. When bound, changes made with a CDO object can be saved back to the ADO object. Therefore, you need only one session when you process items by using both CDO and ADO.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Differences Between CDO and ADO

Although both Microsoft® ActiveX® Data Objects (ADO) and CDO rely on the Exchange OLE DB (ExOLEDB) provider for access to items in Microsoft® Exchange 2000 Server stores, the semantic behaviors of each are different in many respects. The following sections outline these differences.

Synchronized Streams and Properties

Binding to Items in the Web Storage System

Updating Items in the Web Storage System

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Synchronized Streams and Properties

Many items in the Web Storage System contain an associated stream of data that represents the item in serialized format. The properties for the item, therefore, are represented in the stream by using a related Internet standard format. For example, a message item normally contains properties that identify to whom the message is addressed, who the message is from, and a subject. The values of these properties reside in two places: as properties for the item, and in the message stream, formatted according to RFC 822 and RFC 1522 (Multipurpose Internet Mail Extensions (MIME)). The following table represents such an item.

Property | Value
urn:schemas:mailheader:to | "User 1" <user1@microsoft.com>
urn:schemas:mailheader:from | "User 2" <user2@microsoft.com>
urn:schemas:mailheader:subject | You're late for the meeting!
urn:schemas:httpmail:textdescription | We're in room 3607. Come by if you can!
adDefaultStream (-1) | To: "User 1" <user1@microsoft.com> From: "User 2" <user2@microsoft.com> Subject: Meeting in room 3607

When this item is accessed using a Microsoft® ActiveX® Data Objects (ADO) Record object, all of the data, including the stream, is presented in a Fields collection. The stream, which has a special semantic definition within the ADO 2.5 specification, is accessed using the ADO Stream object from within the Fields collection. However, ADO assumes no correlation between the properties for the item and the default stream. That is, if you were to change the urn:schemas:mailheader:to property to "User 3" <user3@microsoft.com>, only the property would change, and the stream would not be updated to reflect the new value. You would have to update the message stream manually.

CDO, on the other hand, keeps the list of properties and the associated stream synchronized for items of certain content classes. If the item in the preceding table were accessed using the CDO Message object, the properties and stream would be coupled, and changes made to properties would be reflected in the stream, and vice versa.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Binding to Items in the Web Storage System

The Microsoft® ActiveX® Data Objects (ADO) Record object uses only one method to bind items in a Web Storage System: the _Record.Open method. This method is used not only to bind to existing items, but also to create new items. You control the behavior of the Open method, such as whether to create a new item or overwrite an existing item, by using various parameters of the method. For example, to open and bind an item for both read and write access, you specify the adModeReadWrite flag in the third parameter. To force the creation of a new item, you specify the adCreateCollection or adCreateNonCollection option in the fourth parameter; adCreateCollection creates a folder item (a collection of other items) and adCreateNonCollection creates a file (non-collection).

CDO objects bind directly to items in the Web Storage System by using the IDataSource Interface Open, SaveTo, and SaveToContainer methods. Both the Open and SaveTo methods are similar to the ADO Open method except that with CDO objects, the initial direction of data flow is defined as part of the method. Open first copies data from the item into the object, and SaveTo saves the data in the object to the item. In both cases, when the operation completes, the CDO object is bound to the item in the store. The SaveToContainer method is just a variation on the SaveTo method that frees the caller from having to invent a unique name for the item in the folder.

When using ADO, you get an item's associated stream by requesting the adDefaultStream (-1) property from the object's Fields collection. When using CDO, the method is different: the CDO IItem and IMessage interfaces define the GetStream Method that returns the item's stream directly.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Updating Items in the Web Storage System

There are operational differences between CDO and Microsoft® ActiveX® Data Objects (ADO) when you update items in the Web Storage System. This section outlines the procedures that are used to update items when using both ADO and CDO.

When you access an item in the Web Storage System by using an ADO Record or Recordset object, a copy of the requested properties is copied into the ADO object. If you decide to make changes to the item's properties, you first alter, append or delete the values by using the associated Fields collection, and then save these changes back to the store by using the Fields.Update method. To recopy the values stored in the store back to the ADO object, you use the Fields.Resync method. If the item has an associated stream, you make changes to it by first retrieving it from the Fields collection by using the special ADO index value of -1. The value of this Field is a reference to an ADO Stream object. After modifying the content within the Stream object, you call _Stream.Flush to commit the changes to the store. The important thing to remember is that there is no inherent correlation between the stream and the properties; both are treated as separate data values for the item.

CDO objects that modify items with streams, on the other hand, do maintain a correlation between the stream and the item's properties. Because of this correlation, modifications to the CDO object's Fields collection are not committed directly to the store when the Fields.Update method is called. Instead, you must invoke the IDataSource. Save method to commit the changes. When the Save call is executed, the item's stream is re-created and saved to the store along with the property values.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Data Sources and Binding

The term data source is intended to be generic, meaning any object or store that can act as a repository of data. Examples of data sources include CDO objects, Microsoft® ActiveX® Data Objects (ADO) objects, Web Storage System items, and Microsoft® Active Directory™ objects. The term binding refers to the state of two objects being associated — or linked — at run time. When you use an OLE DB provider to create or modify an item in the Web Storage System, you first bind the object in the store, and then make changes to its properties or streams. After the data source is bound, the data in the data source can be modified, deleted, created, and so on.

After a binding has occurred, there are two copies of data present: the data in the binding object (the binder) and the data source. For example, when you use an ADO Record object to bind to an existing item in the Web Storage System, the data in the Record object is a copy of the data in the store. Similarly, when you use a CDO Message object to bind to an ADO Record object, the data in the Record object is copied to the Message object. When you make changes to the data in the binding object, these changes are not saved back to the data source automatically; you must commit the changes by using an appropriate method call.

Both ADO and CDO objects can bind to items in the Web Storage System by using an appropriate OLE DB provider. Thus, both ADO and CDO objects can have Web Storage System items as data sources. CDO objects, on the other hand, can have other objects as data sources. For example, a CDO Message object can bind to an ADO Record object, an ADO Stream object, a CDO BodyPart object, or any object exposing an implementation of the IStream interface.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


The IDataSource Interface

The CDO object model defines the core IDataSource Interface for accessing data in other Microsoft® ActiveX® Data Objects (ADO), CDO, and Active Directory™ Service Interfaces (ADSI) objects, or as saved data in the Web Storage System and Microsoft® Active Directory™. All top-level CDO objects expose an implementation of this interface.

CDO objects are bound to items in the Web Storage System by using the IDataSource. Open, IDataSource. SaveTo, and IDataSource. SaveToContainer methods. The Open Method binds to the item, provided by the source URL, and then saves the data from the CDO object to that item. The SaveToContainer Method is similar to SaveTo Method, except that you need only specify the folder (container) in which to save the item; the actual name for the item is a globally unique identifier (GUID) that is generated internally.

All CDO objects provide the ability to bind other CDO, ADO, and ADSI objects. What types of objects a certain CDO can bind to is not part of the core IDataSource Interface definition, but is left to the particular implementation. Object binding follows a similar pattern to Web Storage System item binding. The OpenObject Method first binds the target object and then copies the data in the target object to the opening CDO object. Similarly, the SaveToObject Method first binds the object and then saves the data in the binding CDO object to the target object.

CDO Object   <----- OpenObject ------- Target
CDO Object   -------SaveToObject ----> Target

After a CDO object has been bound to a Web Storage System item or another object, changes made within the CDO object can be saved into the bound data source.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


The Configuration Object

The CDO for Exchange 2000 Server (CDOEX) object model is designed to support a single CDO Configuration object that is shared across a wide array of objects. Each top-level CDO object stores a reference to this central Configuration object through a Configuration property on an associated interface. The following table lists these top-level Component Object Model (COM) classes and the interface through which the Configuration reference is set.

Class | Configuration interface property
Item | IItem.Configuration
Folder | IFolder.Configuration
Message | IMessage.Configuration
CalendarMessage | ICalendarMessage.Configuration
Appointment | IAppointment.Configuration
Person | IPerson.Configuration
Addressee | IAddressee.Configuration

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Web Storage System Search

The Web Storage System is a vast store of resources in a single infrastructure, and search capabilities are provided for locating specific items or to create views of resource data. You can search for items in the Web Storage System using a familiar Structured Query Language (SQL) syntax, which is based on the syntax defined by the Microsoft Indexing Service Query Processor.

When searching the Web Storage System using Microsoft® ActiveX® Data Objects (ADO) or OLE DB, search results are returned in Recordset or Rowset objects. When searching using WebDAV, results are returned as XML elements in the body of an HTTP response.

Indexing properties and implementing full-text indexing improves search performance. For more information about these capabilities, see Property and Full-Text Indexing.

If you are using WebDAV, you can create Search Folders to persist search results in a folder addressable by URLs and also searchable by other queries.

The Microsoft Indexing Service search engine operates by using a system account, enabling it to read all stores, including private mailboxes. To maintain security, Rowset objects returned from an SQL query are evaluated against the access control list (ACL) of the item or folder searched and the security identifier of the user. Any row in which grant access is restricted is removed before the search result is returned.

This section consists of the following topics:

The SELECT Statement

The SELECT * Statement

Search Scope

Related Topics

  • Searching the Web Storage System
  • Web Storage System SQL

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


The SELECT Statement

You can use a SELECT statement to return the values of properties for items in a particular folder or folders within a store. The SELECT statement has the following syntax:

SELECT select-list | *
FROM SCOPE(resource-list)
[WHERE search-condition]
[order-by-clause]

To request specific properties, you enclose each property name in quotation marks and separate each property name with a comma. For example:

SELECT "DAV:href", "DAV:displayname" ...

The search scope to execute is the combination of a folder URL and a traversal depth. For example:

'shallow traversal of "/folder1/"'
'deep traversal of "/folder1/folder2/"'

A full URL can be used as well, as in the following example:

'shallow traversal of "http://server/vroot/folder1"'
'shallow traversal of "file://./backofficestorage/domain.tld/pub2/f1"'

A FROM clause does not require an explicit SCOPE element, in which case a shallow traversal is assumed. For example:

FROM "http://server/vroot/folder1"

If a SCOPE element is specified in the Structured Query Language (SQL) query statement but a depth is not, the Web Storage System query processor assumes a deep traversal, as in the following example:

FROM SCOPE("http://server/vroot/folder1") (deep traversal here)

The Web Storage System does not support deep traversals in the public information store designated for MAPI clients, such as Microsoft® Outlook®. If either an explicit or implicit deep traversal is requested, the Web Storage System query processor returns an error.

Tokens, which are properties in a select list or values in a WHERE clause, must be delimited by single quotations marks. A token can contain only alphabetic characters unless it is also enclosed in double quotation marks. In the following SQL WHERE clause, a full-text search is requested. In the following request string, "this" and "that" are tokens:

WHERE CONTAINS (' "this" AND "that" ')

This clause does not work:

WHERE CONTAINS ('10 dollars')

To fix the clause, surround the token with double quotation marks within the single quotation marks:

WHERE CONTAINS ('"10 dollars"')

Use of the CONTAINS clause is restricted to properties that are marked for full-text indexing, and only if full-text searching has been enabled for that particular store.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


The SELECT * Statement

A SELECT * statement returns all the properties defined by the content classes identified in the expected content class list for the specified folder. When constructing this list of properties to return, the schema scope for the folder is used. If any required schema definition items are not present within this schema scope, only the default properties for items are returned.

Similarly, sending a PROPFIND command using the WebDAV protocol with a depth of 1 to find all item properties returns only the properties defined by the expected content classes of the folder.

Using SELECT * can be an unnecessarily broad use of a Structured Query Language (SQL) query. In most instances, queries with specified property names and other search criteria allow for a much more optimized result. When using SELECT * there are server processing tasks that will be performed due to the unnecessarily broad request, which in most situations is not needed for retrieving a subset of data.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Search Scope

Instead of querying a table as you would a database, you issue a query on a folder scope. A scope is defined as a folder specified by a URL and a depth. You can specify a deep traversal to search a folder and all of its subfolders, or a shallow traversal to search only in the specified folder.

You cannot perform a deep traversal in the MAPI client public store installed by Microsoft® Exchange 2000 Server, but you can perform deep traversals of private stores and in any other public folder trees.

You define a search scope using the SCOPE Structured Query Language (SQL) element. Within the SCOPE element, you define the depths and URLs for the folders to be searched. For shallow searches, you specify 'shallow traversal of'; for deep searches, you specify 'deep traversal of'. After specifying the depth, you specify the URL for each folder. The syntax for this statement is as follows:

SCOPE('shallow traversal of "URL1"' , ['shallow traversal of "URL2"'])
SCOPE('deep traversal of "URL1"', ['deep traversal of "URL2"'])

For example, to find all child folders contained within a particular folder, you execute the following SQL statement:

SELECT "DAV:href", "DAV:displayname"

FROM SCOPE('shallow traversal of "URL"')

WHERE "DAV:isfolder" = True and "DAV:ishidden" = False

This query returns all visible folders in the folder specified by a URL string variable. The traversal is shallow, so subfolders are not searched.

When you execute SQL SELECT commands using the Exchange OLE DB (ExOLEDB) provider, you can use URLs relative to the top-level public folder. Each SELECT command is executed within the context of an OLE DB session (Microsoft® ActiveX® Data Objects (ADO) connection) that implicitly defines the store being searched.

Use of the SCOPE element is optional. If the element is not used, the search depth defaults to shallow. If you specify a SCOPE element but do not specify a depth for a folder, the search defaults to deep traversal. For example, the following statement defaults to a shallow traversal:

SELECT "DAV:href" FROM "URL"

This statement defaults to a deep traversal:

SELECT "DAV:href" FROM SCOPE('"URL"')

When specifying multiple folders in your SCOPE element, you must use the same depth for each folder. You cannot mix deep and shallow searches within the same SQL command.

Only shallow traversal of a single folder is supported in the public folder tree designated for MAPI clients. If you specify deep traversal or multiple folders, an error is returned.

Each SELECT command is executed within the context of an OLE DB session ( ADO connection) that implicitly defines the public information store or mailbox store and the folder tree being searched. When you execute SQL SELECT commands using the ExOLEDB provider, you can use URLs relative to the OLE DB session scope.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Web Storage System Schema

The Web Storage System provides a means to define schema information for items. By using the schema capabilities of the Web Storage System, you can make schema information about your application discoverable to schema-aware applications such as the Web Storage System Structured Query Language (SQL) query processor. Schema information is not rigidly enforced in the Web Storage System as it would be in a relational database system such as Microsoft® SQL Server™. Instead, schema information in the Web Storage System is primarily used to provide a mechanism for schema-aware applications to discover the names of content classes and associated properties used for items in a particular application.

This section consists of the following topics:

Content Classes

Schema Definition Items

Schema Scope

Folder Expected Content Class

Application and Schema Folders

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Content Classes

A Web Storage System content class defines the intent or purpose of an item along with the names of properties that are intended for items in this class.

A content class is different from a content type. A content type defines the type of data that is stored in an item's stream. For example, a common content type is "application/msword"; this content type value indicates that the item's stream contains a Microsoft® Word document in binary form. However, it neither defines the intent or purpose of the Word file to an application nor specifies what properties are stored with the item. For instance, one such file might be a Ph.D. thesis, and another might be a resume'.

A good example of a content class is an expense report. An expense report can be in the format of a Microsoft® Excel worksheet, a Word document, or an e-mail message. However, regardless of the format, there may be a common set of properties stored with the expense report. For example, an expense-tracking application might store the date range in the report, the total dollar amount in the report, and the approval state of the report. Each item stored by the application can have these properties defined, irrespective of the item's content type (e-mail message or Microsoft® Office document).

A content class is used frequently by applications to do the following:

  • Indicate what processing should occur for the specified item.
  • Instantiate an object to render or manipulate the specified item.
  • Enhance the user interface, such as by displaying an icon appropriate for the specified content class.
  • Render items using forms that are based on the specified item's content class.

The following illustration shows the relationship between property and content class definitions and how you can extend a content class, thereby refining and inheriting both its intent and its associated properties.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Content Class and Inheritance

When you create a content class definition, you can inherit properties and semantics defined by other content classes. To extend or refine a content class, you specify its name in the new class's urn:schemas-microsoft-com:xml-data#extends property. An extended (or "derived") content class inherits both the intent of the base class and the properties of the extending content class. The concept of content class inheritance parallels that of class inheritance in programming languages such as Microsoft® Visual C++®.

Single Inheritance

An example of single inheritance is extending the urn:content-classes:person content class for a contact-management application. Your new content class, urn:schemas-domain-tld:content-classes:salesperson, can define additional marketing properties for the contact. Rather than redefining all the properties used with the urn:content-classes:person class for the urn:schemas-domain-tld:content-classes:salesperson class, you instead inherit these properties through extension. The following illustration depicts this inheritance.

Multiple Inheritance

A scenario that demonstrates multiple inheritance and an effective use of content classes is an expense report tailored for delivery as either an e-mail message or a document. To create an application for electronically mailing expense reports, you need access to expense report and message properties; for applications generating expense report documents, you need access to expense report and document properties.

In the following illustration, three content classes (top row) extend the Item content class: message, expensereport, and document. They also serve as base classes for other content classes. The illustration also shows two derived content classes (bottom row): expensemessage and expensedocument. These content classes need properties from their base classes, message and document, respectively. And both classes share a need for expense report properties from expensereport. They do not need to have any additional property definitions.

The e-mail expense report application will use the expensemessage content class, and the document expense report application will use the expensedocument content class. Of course, you can define a content class that inherits from all the base classes; it depends entirely on the needs of the application.

The benefits of inheritance are not only for applications designed for a newer, derived content class, but also for any older applications that can now understand their properties in extended content classes.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Schema Definition Items

In the Web Storage System, schema information is defined using two types of items:

  • Content class definition items. These define the intent or purpose of an item, along with a set of property names that pertain to content of the item’s class. Content class definitions also imply a set of semantics requirements for the item. For example, an item having content class "urn:content-classes:mdn" (Mail Delivery Notification (MDN)) is a message, and it has all the same properties defined as does the "urn:content-classes:message" content class. However, the semantics applied to the message are different in that the MDN class denotes a message that is a notification of delivery of some kind.
  • Property definition items. These define information about a property, such as its name and type. To make a custom property visible to schema-aware applications, you create a definition for the property and then refer to it in a content class definition.

You are not required to create schema information for your application. You can simply add properties to an item if you want, and you do not have to define each property for the content class or property definition.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Property Definitions

Property definitions are items, typically in a designated schema folder, which contain schema information about properties. To create a property definition, create an item and then specify its property values, as described in the following table.

Fully qualified property name | Value
urn:schemas-microsoft-com:xml-data#name | The name of the property. For example: "urn:schemas-domain-tld:propA".
urn:schemas-microsoft-com:datatypes#type | The property's data type. See Data Types.
DAV:contentclass | urn:content-classes:propertydef
urn:schemas-microsoft-com:exch-data:isvisible | True or False. Used to indicate to schema-aware applications whether the property is visible to the client. Typically, you set this to False for properties that your application uses internally, but which you do not intend to be viewed by the application user.
urn:schemas-microsoft-com:exch-data:isindexed | True or False. Indicates whether the property is to be indexed.
urn:schemas-microsoft-com:exch-data:isrequired | True or False. Indicates to schema-aware applications whether the property is required for the specified items.
urn:schemas-microsoft-com:exch-data:ismultivalued | True or False. Indicates to schema-aware applications whether the property is a multivalued property.

Related Topics

  • Creating Property Definitions
  • urn:schemas-microsoft-com:exch-data:
  • Content Class Definitions

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Content Class Definitions

Content class definition items contain properties that define aspects of content stored in the Web Storage System. The following table lists and describes the properties used to define content classes.

Property name | Value
urn:schemas-microsoft-com:xml-data#name | The name of the content class. By convention, content class names are constructed using the same mechanism as property names. For example: "urn:schemas-domain-tld:content-classes:classA".
DAV:contentclass | urn:content-classes:contentclassdef This designates the item as a content class definition item.
urn:schemas-microsoft-com:xml-data#element | A multivalued string containing the names of properties associated with the specified content class. Each referenced property must have a corresponding property definition item within scope.
urn:schemas-microsoft-com:xml-data#extends | A multivalued string containing the names of content classes that the specified class extends or inherits from. Each name must have a corresponding content class definition item within scope.
urn:schemas-microsoft-com:exch-data:expected-content-class | If defining a folder content class, this property is a multivalued string containing the names of content classes expected for items in a folder that belong to this class.

The urn:schemas-microsoft-com:exch-data: namespace contains several other properties that can be attributed to a content class for informational purposes.

Related Topics

  • Creating Content Class Definitions
  • Creating Property Definitions
  • Expected Content Class
  • Schema Scope
  • urn:schemas-microsoft-com:exch-data: namespace

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Schema Scope

Each folder in the Web Storage System has a schema scope. The schema scope is a set of folders, traversed in a particular order, which can contain schema definition items. Each folder can have a different schema scope. The scope can be simple, consisting of only the global schema folder, or complex, containing a large list of folder URLs.

The following two properties from the urn:schemas-microsoft-com:exch-data: namespace are examined on folder items to define a schema scope:

  • schema-collection-ref

    This property is a URL for a folder in which to search for content class and property definitions. This is the first folder searched for schema definition items and is always the first folder in a folder's schema scope. If this property is not set, the default is that store's non_ipm_subtree/Schema folder, which contains the Web Storage System default schema definition items.

  • baseschema

    This property is a multivalued string containing URLs for one or more other folders. You extend the schema scope for a folder by identifying other folders that contain schema definition items.

Applying these two properties to folders, you create a virtual tree of folders in a store that contains schema definition items, starting with the folder identified by schema-collection-ref. When a schema-aware application constructs the schema information for a particular folder, it traverses the entire scope, breadth first, collecting definition items as they are encountered. The following illustration presents one possible schema scope for a folder.

In the preceding diagram:

  • An application folder (not shown in the diagram) identifies folder A as its schema collection folder in its schema-collection-ref property.
  • Folder A is the first folder searched for schema definition items.
  • Folder A has baseschema URLs pointing to folders B and C, which are subsequently searched (in that order) for schema definition items.
  • Folder B has baseschema URLs pointing to folders D and E, which are subsequently searched (in that order) for schema definition items.
  • Folder C has a baseschema URL pointing to folder F, which is the last folder in the scope and the last one searched. Typically, this folder is set to the non_ipm_subtree/Schema folder for that store.
Note The scope tree descends in breadth-first fashion. A breadth-first search works as follows: A is searched first, followed by B and C, and then D, E, and F. This algorithm is not of the recursive-descent type (that is, A, B, D, E, C, F).

Also notice that the scope tree need not, and normally does not, correlate to the actual folder hierarchy in the Web Storage System. This scope tree is virtual in that sense.

In most cases, you should have one folder in your application folder's schema scope that has a baseschema property with one entry pointing to the non_ipm_subtree/Schema folder in that store. This folder contains the default global schema provided by the Web Storage System. If your scope does not contain the non_ipm_subtree/Schema folder, the global schema definition items are not included in your application folder's schema definition.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Folder Expected Content Class

The urn:schemas-microsoft-com:exch-data:expected-content-class property enables you to define the names of expected content classes for items in a particular folder. The list of expected content classes for a folder is information that applications typically use when creating aggregate views of properties for items in that folder. For example, when you issue a WebDAV PROPFIND command for all properties in a folder (Depth = 1), or you issue a SELECT * statement, the list of properties returned is calculated using the definitions of the folder's expected content classes.

There are two ways to set expected content classes:

  • For a specified folder

    Update the urn:schemas-microsoft-com:exch-data:expected-content-class property for the folder item.

  • As part of a content class definition

    This technique is suitable for defining a folder content class, such as with urn:content-classes:contactfolder, which usually contains items having a content class of urn:content-classes:person.

Related Topics

  • Creating Content Class Definitions
  • Schema Scope

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Application and Schema Folders

Schema definition items can be placed in any folder in a particular store and then used to define schemas for your application. By appropriately setting the schema-collection-ref and baseschema properties for various folders, you can bring these definitions into scope.

To avoid complexity when designing and managing your application's schema, plan and organize your schema information. For example, create folders under your top application folder that are designated as schema folders. The following illustration shows a single schema folder under the application folder.

The following table lists possible URLs to the folders in the preceding illustration.

Folder display name | Example URL
application | file://./backofficestorage/domain.microsoft.com/public folders/application/
schema | file://./backofficestorage/domain.microsoft.com/public folders/application/schema/

By placing all schema definition items in designated folders, you decrease the complexity of managing and debugging your application's schema. This is shown in the following illustration.

Arrange the hierarchy of application and schema folders any way you want. As you refine your application, organization is easier with additional schema subfolders.

Related Topics

  • File System Access
  • Property Definitions

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Web Storage System Security

You can control access to an item and its properties using a security descriptor. Using Web Storage System security descriptors, you can:

  • Both grant and deny a trustee access rights to an item and its properties.
  • Identify trustees using a Microsoft® Windows® SID.
  • Set, retrieve, and modify the descriptor in XML format.
  • Access the descriptor using both the Exchange OLE DB (ExOLEDB) provider and WebDAV in XML format.

Each item's security descriptor is accessed through the item's http://schemas.microsoft.com/exchange/security/descriptor property. This property is the item's descriptor in XML format. The descriptor is physically stored and replicated in a Microsoft® Exchange 2000 Server-specific binary format, which is internally based on the standard Windows 2000 descriptor format. The XML representation of the descriptor is not stored directly for the item. When you request this property for an item, the XML string is generated and then returned. When you set this property for an item, the XML string is parsed and the binary descriptor for the item is updated.

The following topics introduce you to the features of Web Storage System security:

Item Access Rights

Web Storage System XML Security Descriptor Format

Related Topics

  • Application Security Module

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Item Access Rights

A Microsoft® Windows® security descriptor defines access rights to a securable object through definition of the object's owner and through a set of access control entries (ACEs) in the descriptor's discretionary access control list (DACL). Each ACE in the DACL either grants or denies a trustee a certain set of access rights to the securable object. The set of rights granted or denied by a particular ACE is contained in its access mask. The access mask is a 32-bit number in which the upper 16 bits define standard and generic access rights and the lower 16 bits define access rights that are object specific.

The following topics list the access rights available for items in the Web Storage System:

Folder Item Access Rights

Non-Folder Item Access Rights

Standard Access Rights

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Folder Item Access Rights

The following table lists the access rights for items that are folders in the Web Storage System.

Access right | Mask (Hex) | Description
fsdrightListContents | 0x00000001 | Same as FILE_LIST_DIRECTORY. Trustee can list file contents.
fsdrightCreateItem | 0x00000002 | Same as FILE_ADD_FILE. Trustee can add a file to a folder.
fsdrightCreateContainer | 0x00000004 | Same as FILE_ADD_SUBDIRECTORY. Trustee can add a subfolder.
fsdrightReadProperty | 0x00000008 | Same as FILE_READ_EA.
fsdrightWriteProperty | 0x00000010 | Same as FILE_WRITE_EA.
fsdrightReadAttributes | 0x00000080 | Same as FILE_READ_ATTRIBUTES. Reserved for future use.
fsdrightWriteAttributes | 0x00000100 | Same as FILE_WRITE_ATTRIBUTES. Reserved for future use.
fsdrightWriteOwnProperty* | 0x0000020 | The trustee can modify his or her own items.
fsdrightDeleteOwnItem | 0x0000040 | The trustee can delete his or her own items.
fsdrightViewItem* | 0x00000800 | The trustee can view items.
fsdrightOwner* | 0x00004000 | The trustee is the owner of the folder. This right corresponds to the frightsOwner right in previous versions of Exchange and is provided for backward compatibility.
fsdrightContact* | 0x00008000 | Not used for security. Identifies the user as the contact for the folder. This right corresponds to the frightsContact right in previous versions of Microsoft® Exchange and is provided for backward compatibility.

* Denotes an Exchange-specific right.

Note For a folder item, the mask containing all the rights in this table is 0xc9ff. This does not include the standard access rights that reside above the 16th bit in the mask (see Standard Access Rights. An example of a mask with all folder item rights and all standard access rights is 0x1fc9ff.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Non-Folder Item Access Rights

The following table lists the access rights for items that are not folders. Many of these access rights are equivalent to their counterparts in Microsoft® Windows® 2000 NTFS file system security.

Access right | Mask (Hex) | Description
fsdrightReadBody | 0x00000001 | Same as FILE_READ_DATA.
fsdrightWriteBody | 0x00000002 | Same as FILE_WRITE_DATA.
fsdrightAppendMsg | 0x00000004 | Same as FILE_WRITE_DATA. Ignored.
fsdrightReadProperty | 0x00000008 | Same as FILE_READ_EA.
fsdrightWriteProperty | 0x00000010 | Same as FILE_WRITE_EA.
fsdrightExecute | 0x00000020 | Same as FILE_EXECUTE. Ignored.
fsdrightReadAttributes | 0x00000080 | Same as FILE_READ_ATTRIBUTES.
fsdrightWriteAttributes | 0x00000100 | Same as FILE_WRITE_ATTRIBUTES.
fsdrightWriteOwnProperty* | 0x00000200 | Trustee can modify his or her own items.
fsdrightDeleteOwnItem* | 0x00000400 | Trustee can delete his or her own items.
fsdrightViewItem* | 0x00000800 | Trustee can view items.

* Denotes a Microsoft® Exchange-specific right.

Note For a non-folder item, the mask containing all the above rights is 0x0fbf. This does not include the standard access rights that reside above the 16th bit in the mask (see Standard Access Rights). An example of a mask with all non-folder item rights and all standard access rights is 0x1f0fbf.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Standard Access Rights

The standard access rights listed in the following table are defined by the Microsoft® Windows® security system and are presented here for completeness. These access rights pertain to the security descriptor. Note that trustees can access or modify portions of the descriptor.

Access right | Mask (Hex) | Description
fsdrightDelete | 0x00010000 | DELETE (standard right)
fsdrightReadControl | 0x00020000 | READ_CONTROL (standard right)
fsdrightWriteSD | 0x00040000 | WRITE_DAC (standard right)
fsdrightWriteOwner | 0x00080000 | WRITE_OWNER (standard right)
fsdrightSynchronize | 0x00100000 | SYNCHRONIZE (standard right)

An example of an access mask with all standard access rights is 0x1f0000.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Web Storage System XML Security Descriptor Format

Each item in the Web Storage System has an associated security descriptor that you can access in XML format using the Exchange OLE DB (ExOLEDB) provider or WebDAV. Any client that can parse and assemble well-formed XML strings that follow the security grammar discussed in this and the following topics can examine and modify the item's descriptor, privileges permitting. For example, all clients that have Microsoft® Internet Explorer 5 have access to the MSXML Component Object Model (COM) component that contains a Document Object Model (DOM) parser, the XMLHTTP COM class, and various other XML-related tools.

The following example provides an outline of the security descriptor grammar in XML. All elements and attributes reside in the http://schemas.microsoft.com/security/ namespace.

<security_descriptor xmlns="http://schemas.microsoft.com/security/">
 <revision>...</revision>
 <owner>...</owner>
 <group>...</group>
 <dacl>...</dacl>
 <sacl>...<sacl>
</security_descriptor>

The structure of the descriptor closely follows the standard structure for Microsoft® Windows® 2000 security descriptors.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Security Identifiers in XML

A SID is used in a security descriptor to identify trustees. In Web Storage System XML format, security identifiers are represented with the XML elements listed in the following table. All elements and attributes reside in the http://schemas.microsoft.com/security/ namespace.

Element name | Possible child elements or contents
sid | string_sid? nt4_compatible_sid? type? ad_object_guid? display_name?
string_sid | Microsoft® Windows® SID in string format; for example, "S-1-1-0".
nt4_compatible_sid | Microsoft® Windows NT® Security Accounts Manager (SAM)-compatible name, for example, "Domain\User".
type | One of the following strings: user group domain alias well_known_group deleted_account invalid unknown computer
ad_object_guid | A globally unique identifier (GUID) in standard string format. This GUID corresponds to the objectGUID attribute for the Microsoft® Active Directory™ object identified by this SID.
display_name | A display name for the specified trustee; for example, Administrator. This display name is derived from the Windows 2000 Active Directory object for this trustee.

The following is an example of a SID in XML format:

<sid>
  <string_sid>S-1-1-0</string_sid>
  <nt4_compatible_name>\Everyone</nt4_compatible_name>
  <type>well_known_group</type>
  <ad_object_guid>{GUID}</ad_object_guid>
  <display_name>Everyone</display_name>
</sid>

SIDs in this format appear in the descriptor's discretionary access control list (DACL) and system audit control list, and are used to define the item's owner and primary group.

When a security descriptor is retrieved for an item, all available elements contained in a SID element are present. However, when you set a security descriptor, you should specify only one of the elements in the SID structure. The most efficient element to use when identifying a trustee is the <string_sid> element. If you don’t know the trustee's SID before you update the descriptor, you can specify (in order of decreasing lookup efficiency) the <nt4_compatible_name> element, the <ad_object_guid> element, or the <display_name> element. From one of these three elements, the Web Storage System determines the trustee's SID by searching Active Directory or a local SAM account database. Using the <display_name> element can cause ambiguity when searching for the user object and should be avoided whenever possible. If multiple entries are present in the SID element, the most efficient element (as previously mentioned) is used.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


XML Security Descriptor XML Elements

Each item's security descriptor is represented in XML with the elements and attributes listed in the tables in this and the following topics. Each security descriptor is expressed using the XML syntax described in the topic Security Identifiers in XML. Note that all items and attributes reside in the http://schemas.microsoft.com/security/ namespace.

Element name | Possible child elements or contents
security_descriptor | Revision, Owner, Group, dacl, sacl,
revision | Decimal number (32 bits)
owner Attributes: defaulted=boolean | sid (see Security Identifiers in XML)
primary_group Attributes: defaulted=boolean | sid (see Security Identifiers in XML)
dacl Attributes: defaulted=boolean protected=boolean autoinherited=boolean | revision, effective_aces, subcontainer_inheritable_aces, subitem_inheritable_aces, (See Discretionary Access Control Lists XML Elements)
sacl Attributes: defaulted=boolean protected=boolean autoinherited=boolean | revision, audit_always, audit_on_failure, audit_on_success,
audit_always | (See System Audit Control Lists XML Elements)
audit_on_failure | (See System Audit Control Lists XML Elements)
audit_on_success | (See System Audit Control Lists XML Elements)

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Discretionary Access Control Lists XML Elements

In a discretionary access control list (DACL), the DACL XML element can contain the elements revision, effective_aces, subitem_inheritable_aces, and subcontainer_inheritable_aces. The following table lists the content models for these elements.

Element name | Child elements or contents
dacl Attributes defaulted=boolean protected=boolean autoinherited=boolean | revision? effective_aces? subitem_inheritable_aces? subcontainer_inheritable_aces?
revision | String; revision for the DACL; for example, 2.
effective_aces | access_allowed_ace* access_denied_ace* access_allowed_object_ace* access_denied_object_ace*
subcontainer_interitable_aces | access_allowed_ace* access_denied_ace* access_allowed_object_ace* access_denied_object_ace*
subitem_interitable_aces | access_allowed_ace* access_denied_ace* access_allowed_object_ace* access_denied_object_ace*
access_allowed_ace Attributes: inherited =boolean (no_propagate_inherit=boolean)^1 | access_mask sid
access_denied_ace Attributes: inherited =boolean (no_propagate_inherit=boolean)^1 | access_mask sid
access_allowed_object_ace Attributes: inherited =boolean (no_propagate_inherit=boolean)^1 (inherited_object_type=GUID)^1 | access_mask sid object_type?
access_denied_object_ace Attributes: inherited =boolean (no_propagate_inherit=boolean)^1 (inherited_object_type=GUID)^1 | access_mask sid (object_type | property_name)?
access_mask | A hexadecimal number in string format; for example, "1fc9ff". This number is the 32-bit access mask for the ACE. This mask identifies the access rights that the ACE grants or denies a trustee.
sid | See Security Identifiers in XML.
object_type | A globally unique identifier (GUID) in standard string format. The GUID identifies the property to which this ACE applies.
property_name | The name of the property. For example, urn:schemas:mailheader:from.

^1 Denotes attributes present in inheritable ACEs. These entries are present in the subcontainer_inheritable_aces and subitem_inheritable_aces elements of the dacl element.

The following example presents an ACL within a descriptor's DACL, in XML format:

<S:dacl S:defaulted="0" S:protected="0" S:autoinherited="1">
  <S:revision>2</S:revision>
  <S:effective_aces>
   <S:access_allowed_ace S:inherited="1">
    <S:access_mask>1f0fbf</S:access_mask>
    <S:sid>
     <S:string_sid>S-1-5-21-507921405-507921405-507921405-500</S:string_sid>
     <S:type>user</S:type>
     <S:nt4_compatible_name>DOMAIN\Administrator</S:nt4_compatible_name>
     <S:ad_object_guid>{446ca8b5-58b5-48b5-88b5-ae41ef9038b5}</S:ad_object_guid>
     <S:display_name>Administrator</S:display_name>
    </S:sid>
   </S:access_allowed_ace>
   <S:access_denied_ace S:inherited="1">
    <S:access_mask>1f0fbf</S:access_mask>
    <S:sid>
     <S:string_sid>S-1-5-7</S:string_sid>
     <S:type>well_known_group</S:type>
     <S:nt4_compatible_name>NT AUTHORITY\ANONYMOUS LOGON</S:nt4_compatible_name>
    </S:sid>
   </S:access_denied_ace>
   <S:access_allowed_ace S:inherited="1">
    <S:access_mask>120ea9</S:access_mask>
    <S:sid>
     <S:string_sid>S-1-1-0</S:string_sid>
     <S:type>well_known_group</S:type>
     <S:nt4_compatible_name>\Everyone</S:nt4_compatible_name>
    </S:sid>
   </S:access_allowed_ace>
  </S:effective_aces>
 </S:dacl>

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


System Audit Control Lists XML Elements

In a system ACL, the sacl XML element can contain the elements revision, audit_always, audit_on_success, and audit_on_failure. The following table lists the content models for these elements.

Element name | Child elements or contents
sacl Attributes: defaulted ="boolean" protected ="boolean" autointerhited="boolean" | revision? audit_always audit_on_failure audit_on_success
revision | String. A revision for the SACL; for example, "2".
audit_always | revision effective_aces subitem_inheritable_aces subcontainer_inheritable_aces
audit_on_failure | revision effective_aces subitem_inheritable_aces subcontainer_inheritable_aces
audit_on_success | revision? effective_aces subitem_inheritable_aces subcontainer_inheritable_aces
system_audit_ace Attributes: inherited =boolean (no_propagate_inherit=boolean)* | access_mask sid
system_audit_object_ace Attributes: inherited =boolean (no_propagate_inherit=boolean)* (inherited_object_type=GUID)* | access_mask sid (object_type | property_name)
access_mask | A hexadecimal number in string format; for example, "1fc9ff". This number is the 32-bit access mask for the ACE.
sid | See Security Identifiers in XML.
object_type | A globally unique identifier (GUID) in standard string format. The GUID or the name identifies the property to which this ACE applies.
property_name | The name of the property. For example, urn:schemas:mailheader:from.

*Denotes attributes present in inheritable ACEs. These entries are present in the subcontainer_inheritable_aces and subitem_inheritable_aces elements.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Example Descriptor in XML

The following example represents a security descriptor in XML format:

<S:security_descriptor xmlns:S="http://schemas.microsoft.com/security/"
      xmlns:D="urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/"
      D:dt="microsoft.security_descriptor">
 <S:revision>1</S:revision>
 <S:owner S:defaulted="0">
  <S:sid>
   <S:string_sid>S-1-5-44-444</S:string_sid>
   <S:type>alias</S:type>
   <S:nt4_compatible_name>BUILTIN\Administrators</S:nt4_compatible_name>
  </S:sid>
 </S:owner>
 <S:primary_group S:defaulted="0">
  <S:sid>
   <S:string_sid>S-1-5-21-555555555-555555555-55555555555-555</S:string_sid>
   <S:type>group</S:type>
   <S:nt4_compatible_name>DOMAIN\Domain Users</S:nt4_compatible_name>
   <S:ad_object_guid>{2bdc2b0c-a8e1-a8e1-a8e1-1a12ec24a8e1}</S:ad_object_guid>
  </S:sid>
 </S:primary_group>
<S:dacl S:defaulted="0" S:protected="0" S:autoinherited="1">
  <S:revision>2</S:revision>
  <S:effective_aces>
   <S:access_allowed_ace S:inherited="1">
    <S:access_mask>1f0fbf</S:access_mask>
    <S:sid>
     <S:string_sid>S-1-5-21-5555555555-5555555555-555555555-599</S:string_sid>
     <S:type>user</S:type>
     <S:nt4_compatible_name>DOMAIN\Administrator</S:nt4_compatible_name>
     <S:ad_object_guid>{48b548b5-48b5-48b5-48b5-48b548b548b5}</S:ad_object_guid>
     <S:display_name>Administrator</S:display_name>
    </S:sid>
   </S:access_allowed_ace>
   <S:access_denied_ace S:inherited="1">
    <S:access_mask>1f0fbf</S:access_mask>
    <S:sid>
     <S:string_sid>S-1-5-7</S:string_sid>
     <S:type>well_known_group</S:type>
     <S:nt4_compatible_name>NT AUTHORITY\ANONYMOUS LOGON</S:nt4_compatible_name>
    </S:sid>
   </S:access_denied_ace>
   <S:access_allowed_ace S:inherited="1">
    <S:access_mask>120ea9</S:access_mask>
    <S:sid>
     <S:string_sid>S-1-1-0</S:string_sid>
     <S:type>well_known_group</S:type>
     <S:nt4_compatible_name>\Everyone</S:nt4_compatible_name>
    </S:sid>
   </S:access_allowed_ace>
  </S:effective_aces>
 </S:dacl>
</S:security_descriptor>

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Accessing Item Descriptors

When generating the XML version of any given descriptor, the item's security properties are not returned automatically. To view or modify an item's descriptor in XML format, you must bind to the item and request the property directly, as in the following example:

Dim Rec as New ADODB.Record
Dim Conn as New ADODB.Connection
Dim Flds as ADODB.Fields
Dim strXMLDesc as String
Dim strXMLAdminDesc as String

Conn.Provider = "ExOLEDB.DataSource"
Conn.Open strItemURL
Rec.Open strItemURL, Conn
Set Flds = Rec.Fields
strXMLDesc=Flds("http://schemas.microsoft.com/exchange/security/descriptor")

Note that access to the item's security descriptor itself is specified using the following standard access rights:

  • READ_CONTROL Only trustees (users and groups) granted the standard READ_CONTROL access right can examine the security descriptor.
  • WRITE_DAC Only trustees granted the WRITE_DAC access right can modify the discretionary access control list (ACL).
  • WRITE_OWNER Only trustees granted the WRITE_OWNER access right can change the item's owner.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


New Item Descriptor Inheritance

When new items are created in folders, they are secured using the ACEs present in the subitem_inheritable_aces section of the parent folder's discretionary access control list (ACL). In a sense, the item inherits a "virtual" descriptor from its parent folder. If the parent folder's descriptor changes, the item automatically inherits the changes.

When you set the descriptor for an item, the "virtual" inheritance is no longer used, and the item's descriptor is used to control access. Therefore, if you make changes to the parent folder's descriptor, items that have had their descriptors set directly do not inherit these changes.

The default behavior described in the preceding paragraphs emulates the folder-based access control system used in earlier versions of Microsoft® Exchange. The drawback to using parent-folder inheritance for items is that the access rights granted or denied to trustees apply uniformly to all items within a given folder that have not had their associated descriptors explicitly set.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Exchange 5.5 Access Rights and the Web Storage System

Previous versions of Microsoft® Exchange 2000 Server supported a custom access control system using the PR_ACL_TABLE table for folders in the store. This access control list (ACL) granted users access rights for each such folder and the items within it. With the Web Storage System, all mailbox stores and one public store are accessible using MAPI and backward compatibility with this access control system. You can use MAPI or Component Object Model (COM) components in the Platform SDK (such as the ACL.DLL component) to grant users the access rights listed in the following table.

Access right | Enables you to | Mask (Hex)
frightsReadAny | Read any items. | 0x001
frightsCreate | Create items. | 0x002
frightsEditOwned | Edit any items owned by the user. | 0x008
frightsDeleteOwned | Delete any items owned by the user. | 0x010
frightsEditAny | Edit any item. | 0x020
frightsDeleteAny | Delete any item. | 0x040
frightsCreateSubfolder | Create subfolders for the specified folder. | 0x080
frightsOwner | Set permissions on the specified folder. | 0x100
frightsContact | Appear as the contact on the specified folder. Not part of rightsAll. | 0x200
frightsFolderVisible | Make the specified folder visible to the trustee. | 0x400
Note Unlike in previous versions of Exchange, in which ACLs were used only at the folder level to grant a user a particular access right, all Web Storage System items (folders and non-folders) can have these rights appear in ACEs that either grant or deny that access right to a trustee.

In the PR_ACL_TABLE property, you identify trustees by using a long-term entry identifier for the user or group in Microsoft® Active Directory™. When the PR_ACL_TABLE table for a folder is updated, the Web Storage System makes adjustments to the item's actual security descriptor.

Access rights for non-folder items and properties cannot be represented using the PR_ACL_TABLE property for a folder. However, property tags for the XML security descriptor are provided in the EDKMDB.h header file in the MSDN® Library, Platform SDK section.

The Exchange Canonical ACL Format

MAPI clients such as Microsoft® Outlook® 2000 display security settings for a folder using information found in the folder's PR_ACL_TABLE property. To give MAPI clients the ability to properly view these settings for folders in the Web Storage System, you need to structure the ACL using the Exchange Canonical ACL format. When you use this format, the PR_ACL_TABLE property is correctly populated with access rights that map to the earlier Exchange security model.

In this format, there are two logical sections in the discretionary ACL for a folder:

  1. ACEs that apply to the folder itself.
  2. ACEs that apply only to items (messages) in the folder. These ACEs are found only in the subitem_inheritable_aces section of the DACL.

Within each of these subsections, the ACEs must be in a particular order, as in the following example:

REPEAT <n>
   GRANT ACCESS RIGHT FOR USER A
   DENY ACCESS RIGHT FOR USER A
REPEAT <m>
   GRANT ACCESS RIGHT FOR DL B
   GRANT ACCESS RIGHT FOR DL C
REPEAT <m>
   GRANT ACCESS DENY FOR DL B
   GRANT ACCESS DENY FOR DL C
REPEAT <0 or 1>
   GRANT ACCESS RIGHT FOR EVERYONE

Both n and m can be 0 (zero).

For example, the following descriptor is in Exchange Canonical ACL format. It defines the security settings presented in the following table when viewed in Outlook 2000. The settings are based on the permission roles presented on the Security property page for the folder item.

Trustee | Outlook permissions role
Default | Author
user8, test (DOMAIN\testuser8) | None
user7, test (DOMAIN\testuser7) | Contributor
user6, test (DOMAIN\testuser6) | Reviewer
user5, test (DOMAIN\testuser5) | Non-editing author
user4, test (DOMAIN\testuser4) | Author
user3, test (DOMAIN\testuser3) | Publishing author
user2, test (DOMAIN\testuser2) | Editor
user1, test (DOMAIN\testuser1) | Publishing editor
user0, test (DOMAIN\testuser0) | Owner
Anonymous | Contributor
testgroup1 (DOMAIN\testgroup1) | Reviewer
testgroup2 (DOMAIN\testgroup2) | Publishing author
<S:security_descriptor xmlns:S="http://schemas.microsoft.com/security/"
   xmlns:D="urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/"
   D:dt="microsoft.security_descriptor">
 <S:revision>1</S:revision>
 <S:owner S:defaulted="0">
  <S:sid>
   <S:string_sid>S-1-5-32-544</S:string_sid>
   <S:type>alias</S:type>
   <S:nt4_compatible_name>BUILTIN\Administrators</S:nt4_compatible_name>
  </S:sid>
 </S:owner>
 <S:primary_group S:defaulted="0">
  <S:sid>
   <S:string_sid>S-1-5-21-527237240-507921405-1708537768-513</S:string_sid>
   <S:type>group</S:type>
   <S:nt4_compatible_name>DOMAIN\Domain Users</S:nt4_compatible_name>
   <S:ad_object_guid>{2bdc2b0c-a8e1-4fd3-8135-1a12ec24d256}</S:ad_object_guid>
  </S:sid>
 </S:primary_group>
 <S:dacl S:defaulted="0" S:protected="0" S:autoinherited="1">
  <S:revision>2</S:revision>
  <S:effective_aces>
   <S:access_allowed_ace S:inherited="0">
    <S:access_mask>1208a9</S:access_mask>
    <S:sid>
     <S:string_sid>S-1-5-21-527237240-507921405-1708537768-1117</S:string_sid>
     <S:type>user</S:type>
     <S:nt4_compatible_name>DOMAIN\testuser8</S:nt4_compatible_name>
     <S:ad_object_guid>{74116535-9aad-4995-957e-99e6640fb69b}</S:ad_object_guid>
     <S:display_name>user8, test</S:display_name>
    </S:sid>
   </S:access_allowed_ace>
   <S:access_denied_ace S:inherited="0">
    <S:access_mask>dc916</S:access_mask>
    <S:sid>
     <S:string_sid>S-1-5-21-527237240-507921405-1708537768-1117</S:string_sid>
     <S:type>user</S:type>
     <S:nt4_compatible_name>DOMAIN\testuser8</S:nt4_compatible_name>
     <S:ad_object_guid>{74116535-9aad-4995-957e-99e6640fb69b}</S:ad_object_guid>
     <S:display_name>user8, test</S:display_name>
    </S:sid>
   </S:access_denied_ace>
   <S:access_allowed_ace S:inherited="0">
    <S:access_mask>1208ab</S:access_mask>
    <S:sid>
     <S:string_sid>S-1-5-21-527237240-507921405-1708537768-1116</S:string_sid>
     <S:type>user</S:type>
     <S:nt4_compatible_name>DOMAIN\testuser7</S:nt4_compatible_name>
     <S:ad_object_guid>{a145c819-2769-4ed7-b8c5-01ac0829d004}</S:ad_object_guid>
     <S:display_name>user7, test</S:display_name>
    </S:sid>
   </S:access_allowed_ace>
   <S:access_denied_ace S:inherited="0">
    <S:access_mask>dc914</S:access_mask>
    <S:sid>
     <S:string_sid>S-1-5-21-527237240-507921405-1708537768-1116</S:string_sid>
     <S:type>user</S:type>
     <S:nt4_compatible_name>DOMAIN\testuser7</S:nt4_compatible_name>
     <S:ad_object_guid>{a145c819-2769-4ed7-b8c5-01ac0829d004}</S:ad_object_guid>
     <S:display_name>user7, test</S:display_name>
    </S:sid>
   </S:access_denied_ace>
   <S:access_allowed_ace S:inherited="0">
    <S:access_mask>1208a9</S:access_mask>
    <S:sid>
     <S:string_sid>S-1-5-21-527237240-507921405-1708537768-1115</S:string_sid>
     <S:type>user</S:type>
     <S:nt4_compatible_name>DOMAIN\testuser6</S:nt4_compatible_name>
     <S:ad_object_guid>{f70d1982-9804-4a7e-8eff-553d193a2756}</S:ad_object_guid>
     <S:display_name>user6, test</S:display_name>
    </S:sid>
   </S:access_allowed_ace>
   <S:access_denied_ace S:inherited="0">
    <S:access_mask>dc916</S:access_mask>
    <S:sid>
     <S:string_sid>S-1-5-21-527237240-507921405-1708537768-1115</S:string_sid>
     <S:type>user</S:type>
     <S:nt4_compatible_name>DOMAIN\testuser6</S:nt4_compatible_name>
     <S:ad_object_guid>{f70d1982-9804-4a7e-8eff-553d193a2756}</S:ad_object_guid>
     <S:display_name>user6, test</S:display_name>
    </S:sid>
   </S:access_denied_ace>
   <S:access_allowed_ace S:inherited="0">
    <S:access_mask>1208ab</S:access_mask>
    <S:sid>
     <S:string_sid>S-1-5-21-527237240-507921405-1708537768-1114</S:string_sid>
     <S:type>user</S:type>
     <S:nt4_compatible_name>DOMAIN\testuser5</S:nt4_compatible_name>
     <S:ad_object_guid>{fb3f5f39-11b1-4071-8956-e1452831ff57}</S:ad_object_guid>
     <S:display_name>user5, test</S:display_name>
    </S:sid>
   </S:access_allowed_ace>
   <S:access_denied_ace S:inherited="0">
    <S:access_mask>dc914</S:access_mask>
    <S:sid>
     <S:string_sid>S-1-5-21-527237240-507921405-1708537768-1114</S:string_sid>
     <S:type>user</S:type>
     <S:nt4_compatible_name>DOMAIN\testuser5</S:nt4_compatible_name>
     <S:ad_object_guid>{fb3f5f39-11b1-4071-8956-e1452831ff57}</S:ad_object_guid>
     <S:display_name>user5, test</S:display_name>
    </S:sid>
   </S:access_denied_ace>
   <S:access_allowed_ace S:inherited="0">
    <S:access_mask>1208ab</S:access_mask>
    <S:sid>
     <S:string_sid>S-1-5-21-527237240-507921405-1708537768-1113</S:string_sid>
     <S:type>user</S:type>
     <S:nt4_compatible_name>DOMAIN\testuser4</S:nt4_compatible_name>
     <S:ad_object_guid>{ec73ab98-1b80-42a6-9887-545400d08c9b}</S:ad_object_guid>
     <S:display_name>user4, test</S:display_name>
    </S:sid>
   </S:access_allowed_ace>
   <S:access_denied_ace S:inherited="0">
    <S:access_mask>dc914</S:access_mask>
    <S:sid>
     <S:string_sid>S-1-5-21-527237240-507921405-1708537768-1113</S:string_sid>
     <S:type>user</S:type>
     <S:nt4_compatible_name>DOMAIN\testuser4</S:nt4_compatible_name>
     <S:ad_object_guid>{ec73ab98-1b80-42a6-9887-545400d08c9b}</S:ad_object_guid>
     <S:display_name>user4, test</S:display_name>
    </S:sid>
   </S:access_denied_ace>
   <S:access_allowed_ace S:inherited="0">
    <S:access_mask>1208af</S:access_mask>
    <S:sid>
     <S:string_sid>S-1-5-21-527237240-507921405-1708537768-1141</S:string_sid>
     <S:type>user</S:type>
     <S:nt4_compatible_name>DOMAIN\testuser3</S:nt4_compatible_name>
     <S:ad_object_guid>{67f9fe57-b2be-4ea5-bf43-bd3888390aaf}</S:ad_object_guid>
     <S:display_name>test user3</S:display_name>
    </S:sid>
   </S:access_allowed_ace>
   <S:access_denied_ace S:inherited="0">
    <S:access_mask>dc910</S:access_mask>
    <S:sid>
     <S:string_sid>S-1-5-21-527237240-507921405-1708537768-1141</S:string_sid>
     <S:type>user</S:type>
     <S:nt4_compatible_name>DOMAIN\testuser3</S:nt4_compatible_name>
     <S:ad_object_guid>{67f9fe57-b2be-4ea5-bf43-bd3888390aaf}</S:ad_object_guid>
     <S:display_name>test user3</S:display_name>
    </S:sid>
   </S:access_denied_ace>
   <S:access_allowed_ace S:inherited="0">
    <S:access_mask>1208ab</S:access_mask>
    <S:sid>
     <S:string_sid>S-1-5-21-527237240-507921405-1708537768-1112</S:string_sid>
     <S:type>user</S:type>
     <S:nt4_compatible_name>DOMAIN\testuser2</S:nt4_compatible_name>
     <S:ad_object_guid>{2ab61a07-e6c0-4c1b-a7fe-ff841ffb240e}</S:ad_object_guid>
     <S:display_name>user2, test</S:display_name>
    </S:sid>
   </S:access_allowed_ace>
   <S:access_denied_ace S:inherited="0">
    <S:access_mask>dc914</S:access_mask>
    <S:sid>
     <S:string_sid>S-1-5-21-527237240-507921405-1708537768-1112</S:string_sid>
     <S:type>user</S:type>
     <S:nt4_compatible_name>DOMAIN\testuser2</S:nt4_compatible_name>
     <S:ad_object_guid>{2ab61a07-e6c0-4c1b-a7fe-ff841ffb240e}</S:ad_object_guid>
     <S:display_name>user2, test</S:display_name>
    </S:sid>
   </S:access_denied_ace>
   <S:access_allowed_ace S:inherited="0">
    <S:access_mask>1208af</S:access_mask>
    <S:sid>
     <S:string_sid>S-1-5-21-527237240-507921405-1708537768-1140</S:string_sid>
     <S:type>user</S:type>
     <S:nt4_compatible_name>DOMAIN\testuser1</S:nt4_compatible_name>
     <S:ad_object_guid>{0724e453-7b94-4161-b224-3f5f45497203}</S:ad_object_guid>
     <S:display_name>test user1</S:display_name>
    </S:sid>
   </S:access_allowed_ace>
   <S:access_denied_ace S:inherited="0">
    <S:access_mask>dc910</S:access_mask>
    <S:sid>
     <S:string_sid>S-1-5-21-527237240-507921405-1708537768-1140</S:string_sid>
     <S:type>user</S:type>
     <S:nt4_compatible_name>DOMAIN\testuser1</S:nt4_compatible_name>
     <S:ad_object_guid>{0724e453-7b94-4161-b224-3f5f45497203}</S:ad_object_guid>
     <S:display_name>test user1</S:display_name>
    </S:sid>
   </S:access_denied_ace>
   <S:access_allowed_ace S:inherited="0">
    <S:access_mask>1fc9ff</S:access_mask>
    <S:sid>
     <S:string_sid>S-1-5-21-527237240-507921405-1708537768-500</S:string_sid>
     <S:type>user</S:type>
     <S:nt4_compatible_name>DOMAIN\testuser0</S:nt4_compatible_name>
     <S:ad_object_guid>{386ca8b5-5a21-4cf7-8d0a-ae41ef903ae6}</S:ad_object_guid>
     <S:display_name>user, test0</S:display_name>
    </S:sid>
   </S:access_allowed_ace>
   <S:access_allowed_ace S:inherited="1">
    <S:access_mask>2</S:access_mask>
    <S:sid>
     <S:string_sid>S-1-5-7</S:string_sid>
     <S:type>well_known_group</S:type>
     <S:nt4_compatible_name>NT AUTHORITY\ANONYMOUS LOGON</S:nt4_compatible_name>
    </S:sid>
   </S:access_allowed_ace>
   <S:access_denied_ace S:inherited="1">
    <S:access_mask>1fc9bd</S:access_mask>
    <S:sid>
     <S:string_sid>S-1-5-7</S:string_sid>
     <S:type>well_known_group</S:type>
     <S:nt4_compatible_name>NT AUTHORITY\ANONYMOUS LOGON</S:nt4_compatible_name>
    </S:sid>
   </S:access_denied_ace>
   <S:access_allowed_ace S:inherited="0">
    <S:access_mask>1208a9</S:access_mask>
    <S:sid>
     <S:string_sid>S-1-5-21-527237240-507921405-1708537768-1142</S:string_sid>
     <S:type>group</S:type>
     <S:nt4_compatible_name>DOMAIN\testgroup1</S:nt4_compatible_name>
     <S:ad_object_guid>{57395759-90f4-4a78-9590-709b86613d06}</S:ad_object_guid>
     <S:display_name>testgroup1</S:display_name>
    </S:sid>
   </S:access_allowed_ace>
   <S:access_allowed_ace S:inherited="0">
    <S:access_mask>1208af</S:access_mask>
    <S:sid>
     <S:string_sid>S-1-5-21-527237240-507921405-1708537768-1143</S:string_sid>
     <S:type>group</S:type>
     <S:nt4_compatible_name>DOMAIN\testgroup2</S:nt4_compatible_name>
     <S:ad_object_guid>{feb5d452-9f83-4765-8e71-1045f01a2e1d}</S:ad_object_guid>
     <S:display_name>testgroup2</S:display_name>
    </S:sid>
   </S:access_allowed_ace>
   <S:access_denied_ace S:inherited="0">
    <S:access_mask>dc916</S:access_mask>
    <S:sid>
     <S:string_sid>S-1-5-21-527237240-507921405-1708537768-1142</S:string_sid>
     <S:type>group</S:type>
     <S:nt4_compatible_name>DOMAIN\testgroup1</S:nt4_compatible_name>
     <S:ad_object_guid>{57395759-90f4-4a78-9590-709b86613d06}</S:ad_object_guid>
     <S:display_name>testgroup1</S:display_name>
    </S:sid>
   </S:access_denied_ace>
   <S:access_denied_ace S:inherited="0">
    <S:access_mask>dc910</S:access_mask>
    <S:sid>
     <S:string_sid>S-1-5-21-527237240-507921405-1708537768-1143</S:string_sid>
     <S:type>group</S:type>
     <S:nt4_compatible_name>DOMAIN\testgroup2</S:nt4_compatible_name>
     <S:ad_object_guid>{feb5d452-9f83-4765-8e71-1045f01a2e1d}</S:ad_object_guid>
     <S:display_name>testgroup2</S:display_name>
    </S:sid>
   </S:access_denied_ace>
   <S:access_allowed_ace S:inherited="1">
    <S:access_mask>1208ab</S:access_mask>
    <S:sid>
     <S:string_sid>S-1-1-0</S:string_sid>
     <S:type>well_known_group</S:type>
     <S:nt4_compatible_name>\Everyone</S:nt4_compatible_name>
    </S:sid>
   </S:access_allowed_ace>
  </S:effective_aces>
  <S:subcontainer_inheritable_aces>
   <S:access_allowed_ace S:inherited="0" S:no_propagate_inherit="0">
    <S:access_mask>1208a9</S:access_mask>
    <S:sid>
     <S:string_sid>S-1-5-21-527237240-507921405-1708537768-1117</S:string_sid>
     <S:type>user</S:type>
     <S:nt4_compatible_name>DOMAIN\testuser8</S:nt4_compatible_name>
     <S:ad_object_guid>{74116535-9aad-4995-957e-99e6640fb69b}</S:ad_object_guid>
     <S:display_name>user8, test</S:display_name>
    </S:sid>
   </S:access_allowed_ace>
   <S:access_denied_ace S:inherited="0" S:no_propagate_inherit="0">
    <S:access_mask>dc916</S:access_mask>
    <S:sid>
     <S:string_sid>S-1-5-21-527237240-507921405-1708537768-1117</S:string_sid>
     <S:type>user</S:type>
     <S:nt4_compatible_name>DOMAIN\testuser8</S:nt4_compatible_name>
     <S:ad_object_guid>{74116535-9aad-4995-957e-99e6640fb69b}</S:ad_object_guid>
     <S:display_name>user8, test</S:display_name>
    </S:sid>
   </S:access_denied_ace>
   <S:access_allowed_ace S:inherited="0" S:no_propagate_inherit="0">
    <S:access_mask>1208ab</S:access_mask>
    <S:sid>
     <S:string_sid>S-1-5-21-527237240-507921405-1708537768-1116</S:string_sid>
     <S:type>user</S:type>
     <S:nt4_compatible_name>DOMAIN\testuser7</S:nt4_compatible_name>
     <S:ad_object_guid>{a145c819-2769-4ed7-b8c5-01ac0829d004}</S:ad_object_guid>
     <S:display_name>user7, test</S:display_name>
    </S:sid>
   </S:access_allowed_ace>
   <S:access_denied_ace S:inherited="0" S:no_propagate_inherit="0">
    <S:access_mask>dc914</S:access_mask>
    <S:sid>
     <S:string_sid>S-1-5-21-527237240-507921405-1708537768-1116</S:string_sid>
     <S:type>user</S:type>
     <S:nt4_compatible_name>DOMAIN\testuser7</S:nt4_compatible_name>
     <S:ad_object_guid>{a145c819-2769-4ed7-b8c5-01ac0829d004}</S:ad_object_guid>
     <S:display_name>user7, test</S:display_name>
    </S:sid>
   </S:access_denied_ace>
   <S:access_allowed_ace S:inherited="0" S:no_propagate_inherit="0">
    <S:access_mask>1208a9</S:access_mask>
    <S:sid>
     <S:string_sid>S-1-5-21-527237240-507921405-1708537768-1115</S:string_sid>
     <S:type>user</S:type>
     <S:nt4_compatible_name>DOMAIN\testuser6</S:nt4_compatible_name>
     <S:ad_object_guid>{f70d1982-9804-4a7e-8eff-553d193a2756}</S:ad_object_guid>
     <S:display_name>user6, test</S:display_name>
    </S:sid>
   </S:access_allowed_ace>
   <S:access_denied_ace S:inherited="0" S:no_propagate_inherit="0">
    <S:access_mask>dc916</S:access_mask>
    <S:sid>
     <S:string_sid>S-1-5-21-527237240-507921405-1708537768-1115</S:string_sid>
     <S:type>user</S:type>
     <S:nt4_compatible_name>DOMAIN\testuser6</S:nt4_compatible_name>
     <S:ad_object_guid>{f70d1982-9804-4a7e-8eff-553d193a2756}</S:ad_object_guid>
     <S:display_name>user6, test</S:display_name>
    </S:sid>
   </S:access_denied_ace>
   <S:access_allowed_ace S:inherited="0" S:no_propagate_inherit="0">
    <S:access_mask>1208ab</S:access_mask>
    <S:sid>
     <S:string_sid>S-1-5-21-527237240-507921405-1708537768-1114</S:string_sid>
     <S:type>user</S:type>
     <S:nt4_compatible_name>DOMAIN\testuser5</S:nt4_compatible_name>
     <S:ad_object_guid>{fb3f5f39-11b1-4071-8956-e1452831ff57}</S:ad_object_guid>
     <S:display_name>user5, test</S:display_name>
    </S:sid>
   </S:access_allowed_ace>
   <S:access_denied_ace S:inherited="0" S:no_propagate_inherit="0">
    <S:access_mask>dc914</S:access_mask>
    <S:sid>
     <S:string_sid>S-1-5-21-527237240-507921405-1708537768-1114</S:string_sid>
     <S:type>user</S:type>
     <S:nt4_compatible_name>DOMAIN\testuser5</S:nt4_compatible_name>
     <S:ad_object_guid>{fb3f5f39-11b1-4071-8956-e1452831ff57}</S:ad_object_guid>
     <S:display_name>user5, test</S:display_name>
    </S:sid>
   </S:access_denied_ace>
   <S:access_allowed_ace S:inherited="0" S:no_propagate_inherit="0">
    <S:access_mask>1208ab</S:access_mask>
    <S:sid>
     <S:string_sid>S-1-5-21-527237240-507921405-1708537768-1113</S:string_sid>
     <S:type>user</S:type>
     <S:nt4_compatible_name>DOMAIN\testuser4</S:nt4_compatible_name>
     <S:ad_object_guid>{ec73ab98-1b80-42a6-9887-545400d08c9b}</S:ad_object_guid>
     <S:display_name>user4, test</S:display_name>
    </S:sid>
   </S:access_allowed_ace>
   <S:access_denied_ace S:inherited="0" S:no_propagate_inherit="0">
    <S:access_mask>dc914</S:access_mask>
    <S:sid>
     <S:string_sid>S-1-5-21-527237240-507921405-1708537768-1113</S:string_sid>
     <S:type>user</S:type>
     <S:nt4_compatible_name>DOMAIN\testuser4</S:nt4_compatible_name>
     <S:ad_object_guid>{ec73ab98-1b80-42a6-9887-545400d08c9b}</S:ad_object_guid>
     <S:display_name>user4, test</S:display_name>
    </S:sid>
   </S:access_denied_ace>
   <S:access_allowed_ace S:inherited="0" S:no_propagate_inherit="0">
    <S:access_mask>1208af</S:access_mask>
    <S:sid>
     <S:string_sid>S-1-5-21-527237240-507921405-1708537768-1141</S:string_sid>
     <S:type>user</S:type>
     <S:nt4_compatible_name>DOMAIN\testuser3</S:nt4_compatible_name>
     <S:ad_object_guid>{67f9fe57-b2be-4ea5-bf43-bd3888390aaf}</S:ad_object_guid>
     <S:display_name>test user3</S:display_name>
    </S:sid>
   </S:access_allowed_ace>
   <S:access_denied_ace S:inherited="0" S:no_propagate_inherit="0">
    <S:access_mask>dc910</S:access_mask>
    <S:sid>
     <S:string_sid>S-1-5-21-527237240-507921405-1708537768-1141</S:string_sid>
     <S:type>user</S:type>
     <S:nt4_compatible_name>DOMAIN\testuser3</S:nt4_compatible_name>
     <S:ad_object_guid>{67f9fe57-b2be-4ea5-bf43-bd3888390aaf}</S:ad_object_guid>
     <S:display_name>test user3</S:display_name>
    </S:sid>
   </S:access_denied_ace>
   <S:access_allowed_ace S:inherited="0" S:no_propagate_inherit="0">
    <S:access_mask>1208ab</S:access_mask>
    <S:sid>
     <S:string_sid>S-1-5-21-527237240-507921405-1708537768-1112</S:string_sid>
     <S:type>user</S:type>
     <S:nt4_compatible_name>DOMAIN\testuser2</S:nt4_compatible_name>
     <S:ad_object_guid>{2ab61a07-e6c0-4c1b-a7fe-ff841ffb240e}</S:ad_object_guid>
     <S:display_name>user2, test</S:display_name>
    </S:sid>
   </S:access_allowed_ace>
   <S:access_denied_ace S:inherited="0" S:no_propagate_inherit="0">
    <S:access_mask>dc914</S:access_mask>
    <S:sid>
     <S:string_sid>S-1-5-21-527237240-507921405-1708537768-1112</S:string_sid>
     <S:type>user</S:type>
     <S:nt4_compatible_name>DOMAIN\testuser2</S:nt4_compatible_name>
     <S:ad_object_guid>{2ab61a07-e6c0-4c1b-a7fe-ff841ffb240e}</S:ad_object_guid>
     <S:display_name>user2, test</S:display_name>
    </S:sid>
   </S:access_denied_ace>
   <S:access_allowed_ace S:inherited="0" S:no_propagate_inherit="0">
    <S:access_mask>1208af</S:access_mask>
    <S:sid>
     <S:string_sid>S-1-5-21-527237240-507921405-1708537768-1140</S:string_sid>
     <S:type>user</S:type>
     <S:nt4_compatible_name>DOMAIN\testuser1</S:nt4_compatible_name>
     <S:ad_object_guid>{0724e453-7b94-4161-b224-3f5f45497203}</S:ad_object_guid>
     <S:display_name>test user1</S:display_name>
    </S:sid>
   </S:access_allowed_ace>
   <S:access_denied_ace S:inherited="0" S:no_propagate_inherit="0">
    <S:access_mask>dc910</S:access_mask>
    <S:sid>
     <S:string_sid>S-1-5-21-527237240-507921405-1708537768-1140</S:string_sid>
     <S:type>user</S:type>
     <S:nt4_compatible_name>DOMAIN\testuser1</S:nt4_compatible_name>
     <S:ad_object_guid>{0724e453-7b94-4161-b224-3f5f45497203}</S:ad_object_guid>
     <S:display_name>test user1</S:display_name>
    </S:sid>
   </S:access_denied_ace>
   <S:access_allowed_ace S:inherited="0" S:no_propagate_inherit="0">
    <S:access_mask>1fc9ff</S:access_mask>
    <S:sid>
     <S:string_sid>S-1-5-21-527237240-507921405-1708537768-500</S:string_sid>
     <S:type>user</S:type>
     <S:nt4_compatible_name>DOMAIN\testuser0</S:nt4_compatible_name>
     <S:ad_object_guid>{386ca8b5-5a21-4cf7-8d0a-ae41ef903ae6}</S:ad_object_guid>
     <S:display_name>user0, test</S:display_name>
    </S:sid>
   </S:access_allowed_ace>
   <S:access_allowed_ace S:inherited="1" S:no_propagate_inherit="0">
    <S:access_mask>2</S:access_mask>
    <S:sid>
     <S:string_sid>S-1-5-7</S:string_sid>
     <S:type>well_known_group</S:type>
     <S:nt4_compatible_name>NT AUTHORITY\ANONYMOUS LOGON</S:nt4_compatible_name>
    </S:sid>
   </S:access_allowed_ace>
   <S:access_denied_ace S:inherited="1" S:no_propagate_inherit="0">
    <S:access_mask>1fc9bd</S:access_mask>
    <S:sid>
     <S:string_sid>S-1-5-7</S:string_sid>
     <S:type>well_known_group</S:type>
     <S:nt4_compatible_name>NT AUTHORITY\ANONYMOUS LOGON</S:nt4_compatible_name>
    </S:sid>
   </S:access_denied_ace>
   <S:access_allowed_ace S:inherited="0" S:no_propagate_inherit="0">
    <S:access_mask>1208a9</S:access_mask>
    <S:sid>
     <S:string_sid>S-1-5-21-527237240-507921405-1708537768-1142</S:string_sid>
     <S:type>group</S:type>
     <S:nt4_compatible_name>DOMAIN\testgroup1</S:nt4_compatible_name>
     <S:ad_object_guid>{57395759-90f4-4a78-9590-709b86613d06}</S:ad_object_guid>
     <S:display_name>testgroup1</S:display_name>
    </S:sid>
   </S:access_allowed_ace>
   <S:access_allowed_ace S:inherited="0" S:no_propagate_inherit="0">
    <S:access_mask>1208af</S:access_mask>
    <S:sid>
     <S:string_sid>S-1-5-21-527237240-507921405-1708537768-1143</S:string_sid>
     <S:type>group</S:type>
     <S:nt4_compatible_name>DOMAIN\testgroup2</S:nt4_compatible_name>
     <S:ad_object_guid>{feb5d452-9f83-4765-8e71-1045f01a2e1d}</S:ad_object_guid>
     <S:display_name>testgroup2</S:display_name>
    </S:sid>
   </S:access_allowed_ace>
   <S:access_denied_ace S:inherited="0" S:no_propagate_inherit="0">
    <S:access_mask>dc916</S:access_mask>
    <S:sid>
     <S:string_sid>S-1-5-21-527237240-507921405-1708537768-1142</S:string_sid>
     <S:type>group</S:type>
     <S:nt4_compatible_name>DOMAIN\testgroup1</S:nt4_compatible_name>
     <S:ad_object_guid>{57395759-90f4-4a78-9590-709b86613d06}</S:ad_object_guid>
     <S:display_name>testgroup1</S:display_name>
    </S:sid>
   </S:access_denied_ace>
   <S:access_denied_ace S:inherited="0" S:no_propagate_inherit="0">
    <S:access_mask>dc910</S:access_mask>
    <S:sid>
     <S:string_sid>S-1-5-21-527237240-507921405-1708537768-1143</S:string_sid>
     <S:type>group</S:type>
     <S:nt4_compatible_name>DOMAIN\testgroup2</S:nt4_compatible_name>
     <S:ad_object_guid>{feb5d452-9f83-4765-8e71-1045f01a2e1d}</S:ad_object_guid>
     <S:display_name>testgroup2</S:display_name>
    </S:sid>
   </S:access_denied_ace>
   <S:access_allowed_ace S:inherited="1" S:no_propagate_inherit="0">
    <S:access_mask>1208ab</S:access_mask>
    <S:sid>
     <S:string_sid>S-1-1-0</S:string_sid>
     <S:type>well_known_group</S:type>
     <S:nt4_compatible_name>\Everyone</S:nt4_compatible_name>
    </S:sid>
   </S:access_allowed_ace>
  </S:subcontainer_inheritable_aces>
  <S:subitem_inheritable_aces>
   <S:access_denied_ace S:inherited="0" S:no_propagate_inherit="0">
    <S:access_mask>1f0fbf</S:access_mask>
    <S:sid>
     <S:string_sid>S-1-5-21-527237240-507921405-1708537768-1117</S:string_sid>
     <S:type>user</S:type>
     <S:nt4_compatible_name>DOMAIN\testuser8</S:nt4_compatible_name>
     <S:ad_object_guid>{74116535-9aad-4995-957e-99e6640fb69b}</S:ad_object_guid>
     <S:display_name>user8, test</S:display_name>
    </S:sid>
   </S:access_denied_ace>
   <S:access_denied_ace S:inherited="0" S:no_propagate_inherit="0">
    <S:access_mask>1f0fbf</S:access_mask>
    <S:sid>
     <S:string_sid>S-1-5-21-527237240-507921405-1708537768-1116</S:string_sid>
     <S:type>user</S:type>
     <S:nt4_compatible_name>DOMAIN\testuser7</S:nt4_compatible_name>
     <S:ad_object_guid>{a145c819-2769-4ed7-b8c5-01ac0829d004}</S:ad_object_guid>
     <S:display_name>user7, test</S:display_name>
    </S:sid>
   </S:access_denied_ace>
   <S:access_allowed_ace S:inherited="0" S:no_propagate_inherit="0">
    <S:access_mask>1208a9</S:access_mask>
    <S:sid>
     <S:string_sid>S-1-5-21-527237240-507921405-1708537768-1115</S:string_sid>
     <S:type>user</S:type>
     <S:nt4_compatible_name>DOMAIN\testuser6</S:nt4_compatible_name>
     <S:ad_object_guid>{f70d1982-9804-4a7e-8eff-553d193a2756}</S:ad_object_guid>
     <S:display_name>user6, test</S:display_name>
    </S:sid>
   </S:access_allowed_ace>
   <S:access_denied_ace S:inherited="0" S:no_propagate_inherit="0">
    <S:access_mask>1f0716</S:access_mask>
    <S:sid>
     <S:string_sid>S-1-5-21-527237240-507921405-1708537768-1115</S:string_sid>
     <S:type>user</S:type>
     <S:nt4_compatible_name>DOMAIN\testuser6</S:nt4_compatible_name>
     <S:ad_object_guid>{f70d1982-9804-4a7e-8eff-553d193a2756}</S:ad_object_guid>
     <S:display_name>user6, test</S:display_name>
    </S:sid>
   </S:access_denied_ace>
   <S:access_allowed_ace S:inherited="0" S:no_propagate_inherit="0">
    <S:access_mask>120ca9</S:access_mask>
    <S:sid>
     <S:string_sid>S-1-5-21-527237240-507921405-1708537768-1114</S:string_sid>
     <S:type>user</S:type>
     <S:nt4_compatible_name>DOMAIN\testuser5</S:nt4_compatible_name>
     <S:ad_object_guid>{fb3f5f39-11b1-4071-8956-e1452831ff57}</S:ad_object_guid>
     <S:display_name>user5, test</S:display_name>
    </S:sid>
   </S:access_allowed_ace>
   <S:access_denied_ace S:inherited="0" S:no_propagate_inherit="0">
    <S:access_mask>1f0716</S:access_mask>
    <S:sid>
     <S:string_sid>S-1-5-21-527237240-507921405-1708537768-1114</S:string_sid>
     <S:type>user</S:type>
     <S:nt4_compatible_name>DOMAIN\testuser5</S:nt4_compatible_name>
     <S:ad_object_guid>{fb3f5f39-11b1-4071-8956-e1452831ff57}</S:ad_object_guid>
     <S:display_name>user5, test</S:display_name>
    </S:sid>
   </S:access_denied_ace>
   <S:access_allowed_ace S:inherited="0" S:no_propagate_inherit="0">
    <S:access_mask>120ea9</S:access_mask>
    <S:sid>
     <S:string_sid>S-1-5-21-527237240-507921405-1708537768-1113</S:string_sid>
     <S:type>user</S:type>
     <S:nt4_compatible_name>DOMAIN\testuser4</S:nt4_compatible_name>
     <S:ad_object_guid>{ec73ab98-1b80-42a6-9887-545400d08c9b}</S:ad_object_guid>
     <S:display_name>user4, test</S:display_name>
    </S:sid>
   </S:access_allowed_ace>
   <S:access_denied_ace S:inherited="0" S:no_propagate_inherit="0">
    <S:access_mask>1f0716</S:access_mask>
    <S:sid>
     <S:string_sid>S-1-5-21-527237240-507921405-1708537768-1113</S:string_sid>
     <S:type>user</S:type>
     <S:nt4_compatible_name>DOMAIN\testuser4</S:nt4_compatible_name>
     <S:ad_object_guid>{ec73ab98-1b80-42a6-9887-545400d08c9b}</S:ad_object_guid>
     <S:display_name>user4, test</S:display_name>
    </S:sid>
   </S:access_denied_ace>
   <S:access_allowed_ace S:inherited="0" S:no_propagate_inherit="0">
    <S:access_mask>120ea9</S:access_mask>
    <S:sid>
     <S:string_sid>S-1-5-21-527237240-507921405-1708537768-1141</S:string_sid>
     <S:type>user</S:type>
     <S:nt4_compatible_name>DOMAIN\testuser3</S:nt4_compatible_name>
     <S:ad_object_guid>{67f9fe57-b2be-4ea5-bf43-bd3888390aaf}</S:ad_object_guid>
     <S:display_name>test user3</S:display_name>
    </S:sid>
   </S:access_allowed_ace>
   <S:access_denied_ace S:inherited="0" S:no_propagate_inherit="0">
    <S:access_mask>1f0716</S:access_mask>
    <S:sid>
     <S:string_sid>S-1-5-21-527237240-507921405-1708537768-1141</S:string_sid>
     <S:type>user</S:type>
     <S:nt4_compatible_name>DOMAIN\testuser3</S:nt4_compatible_name>
     <S:ad_object_guid>{67f9fe57-b2be-4ea5-bf43-bd3888390aaf}</S:ad_object_guid>
     <S:display_name>test user3</S:display_name>
    </S:sid>
   </S:access_denied_ace>
   <S:access_allowed_ace S:inherited="0" S:no_propagate_inherit="0">
    <S:access_mask>1f0fbf</S:access_mask>
    <S:sid>
     <S:string_sid>S-1-5-21-527237240-507921405-1708537768-1112</S:string_sid>
     <S:type>user</S:type>
     <S:nt4_compatible_name>DOMAIN\testuser2</S:nt4_compatible_name>
     <S:ad_object_guid>{2ab61a07-e6c0-4c1b-a7fe-ff841ffb240e}</S:ad_object_guid>
     <S:display_name>user2, test</S:display_name>
    </S:sid>
   </S:access_allowed_ace>
   <S:access_allowed_ace S:inherited="0" S:no_propagate_inherit="0">
    <S:access_mask>1f0fbf</S:access_mask>
    <S:sid>
     <S:string_sid>S-1-5-21-527237240-507921405-1708537768-1140</S:string_sid>
     <S:type>user</S:type>
     <S:nt4_compatible_name>DOMAIN\testuser1</S:nt4_compatible_name>
     <S:ad_object_guid>{0724e453-7b94-4161-b224-3f5f45497203}</S:ad_object_guid>
     <S:display_name>test user1</S:display_name>
    </S:sid>
   </S:access_allowed_ace>
   <S:access_allowed_ace S:inherited="0" S:no_propagate_inherit="0">
    <S:access_mask>1f0fbf</S:access_mask>
    <S:sid>
     <S:string_sid>S-1-5-21-527237240-507921405-1708537768-500</S:string_sid>
     <S:type>user</S:type>
     <S:nt4_compatible_name>DOMAIN\testuser0</S:nt4_compatible_name>
     <S:ad_object_guid>{386ca8b5-5a21-4cf7-8d0a-ae41ef903ae6}</S:ad_object_guid>
     <S:display_name>user0, test</S:display_name>
    </S:sid>
   </S:access_allowed_ace>
   <S:access_denied_ace S:inherited="1" S:no_propagate_inherit="0">
    <S:access_mask>1f0fbf</S:access_mask>
    <S:sid>
     <S:string_sid>S-1-5-7</S:string_sid>
     <S:type>well_known_group</S:type>
     <S:nt4_compatible_name>NT AUTHORITY\ANONYMOUS LOGON</S:nt4_compatible_name>
    </S:sid>
   </S:access_denied_ace>
   <S:access_allowed_ace S:inherited="0" S:no_propagate_inherit="0">
    <S:access_mask>1208a9</S:access_mask>
    <S:sid>
     <S:string_sid>S-1-5-21-527237240-507921405-1708537768-1142</S:string_sid>
     <S:type>group</S:type>
     <S:nt4_compatible_name>DOMAIN\testgroup1</S:nt4_compatible_name>
     <S:ad_object_guid>{57395759-90f4-4a78-9590-709b86613d06}</S:ad_object_guid>
     <S:display_name>testgroup1</S:display_name>
    </S:sid>
   </S:access_allowed_ace>
   <S:access_allowed_ace S:inherited="0" S:no_propagate_inherit="0">
    <S:access_mask>120ea9</S:access_mask>
    <S:sid>
     <S:string_sid>S-1-5-21-527237240-507921405-1708537768-1143</S:string_sid>
     <S:type>group</S:type>
     <S:nt4_compatible_name>DOMAIN\testgroup2</S:nt4_compatible_name>
     <S:ad_object_guid>{feb5d452-9f83-4765-8e71-1045f01a2e1d}</S:ad_object_guid>
     <S:display_name>testgroup2</S:display_name>
    </S:sid>
   </S:access_allowed_ace>
   <S:access_denied_ace S:inherited="0" S:no_propagate_inherit="0">
    <S:access_mask>1f0716</S:access_mask>
    <S:sid>
     <S:string_sid>S-1-5-21-527237240-507921405-1708537768-1142</S:string_sid>
     <S:type>group</S:type>
     <S:nt4_compatible_name>DOMAIN\testgroup1</S:nt4_compatible_name>
     <S:ad_object_guid>{57395759-90f4-4a78-9590-709b86613d06}</S:ad_object_guid>
     <S:display_name>testgroup1</S:display_name>
    </S:sid>
   </S:access_denied_ace>
   <S:access_denied_ace S:inherited="0" S:no_propagate_inherit="0">
    <S:access_mask>1f0716</S:access_mask>
    <S:sid>
     <S:string_sid>S-1-5-21-527237240-507921405-1708537768-1143</S:string_sid>
     <S:type>group</S:type>
     <S:nt4_compatible_name>DOMAIN\testgroup2</S:nt4_compatible_name>
     <S:ad_object_guid>{feb5d452-9f83-4765-8e71-1045f01a2e1d}</S:ad_object_guid>
     <S:display_name>testgroup2</S:display_name>
    </S:sid>
   </S:access_denied_ace>
   <S:access_allowed_ace S:inherited="1" S:no_propagate_inherit="0">
    <S:access_mask>120ea9</S:access_mask>
    <S:sid>
     <S:string_sid>S-1-1-0</S:string_sid>
     <S:type>well_known_group</S:type>
     <S:nt4_compatible_name>\Everyone</S:nt4_compatible_name>
    </S:sid>
   </S:access_allowed_ace>
  </S:subitem_inheritable_aces>
 </S:dacl>
</S:security_descriptor>

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Web Storage System Events

The following topic covers how you can programmatically respond to events that occur in the Web Storage System. With events, you can write your own custom logic that executes on the server in response to changes in the data in the Web Storage System.

This topic explains how to register, modify, and monitor events; how to write event sink Component Object Model (COM) classes; and how to respond to event notifications when the event sink class receives them.

Note Mail messages processed in event sinks must be in a Request for Comments (RFC-822) compliant state and end with a carriage return/line feed (CR/LF).

This topic covers the following information:

Web Storage System Event Terms

Events Overview

Events and Event Sink Interfaces

Event Registration

Event Reliability

Working in an Event Sink

Security in an Event Sink

The Script Host Sink

Event Naming

Event Naming in Scripts

Sink Monitoring

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Web Storage System Event Terms

Event, Store Event

A change in the store for which you can receive programmatic notification by means of an event sink.

Event Sink

A custom Component Object Model (COM) class or script that is called to process an event that occurs in the store, according to the properties specified in an event registration.

Event Methods

Methods in the event sink that Microsoft® Exchange calls to notify you that an event occurred.

Event Registration

A logical connection between an event and an event sink that is created by a special type of store item. The connection is such that when an event occurs that meets the event registration criteria, the appropriate event method is called in the event sink.

Event Notification

The process whereby Exchange detects an event occurrence that matches an event registration's criteria, creates an instance of the event sink specified in the event registration, and calls the appropriate event method.

Top-Level Folders

Folders in Web Storage System that have no parent folders (root folders).

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Events Overview

Events occur when Web Storage System items are saved, deleted, moved, copied, or modified; when a MDB is started or stopped; or when a specific time interval has elapsed. You can write event sinks (Component Object Model (COM) objects or scripts) that can receive notification of these events.

Typical Applications

Typical applications that use event sinks include the following:

Timers

You can register to receive notifications at specified times. A timer can be used to synchronize information external to the store, periodically clean up the store, remind people of pending tasks, or trigger batch processing.

Notifications

You can register to receive an event, and then in the event sink you can notify other parties that the event has occurred.

Automatic Categorization

An item being saved to the store could be analyzed and categorized so that data is properly stored and information about the data is kept up-to-date.

Workflow Applications

You can register to receive event notifications when workflow items are moved in the Web Storage System. The event sink can programmatically handle the workflow item as it moves along on its workflow path.

Item Validation

Event sinks can validate or check items when they are saved to the store. The event sink might process a delete notification by checking a custom criterion to see if the person deleting the item has the rights to do so. When a save event occurs, you might check the formatting of the item being saved.

Store Maintenance

Whenever an item is deleted from a particular location in the store, other items that are outside the Web Storage System may need to be modified or deleted. The event sink could automatically handle this task.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Exchange Calls Event Methods

The event sink can be a Component Object Model (COM) class with interfaces and event methods defined by Microsoft® Exchange. To notify the event sink, Exchange creates an instance of the event sink COM class, obtains the appropriate interface, and invokes the appropriate event method.

The following illustration shows how Exchange calls the event sink.

A | An item is saved to the store, causing a store event.
B | Exchange obtains the required interface in the event sink.
C | Exchange calls the event method for the given event notification.

Note This same process takes place if the event sink is a script, except that a special COM object (the Script Host) is called, which then runs the appropriate event method in the script.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Multiple Events

The following illustration shows that events can occur anywhere in the Web Storage System and that the same event sink class can be called for numerous Web Storage System events.

You register with the server to receive event notifications by saving a registration item to the store. Where you save the item defines the scope (location and range) of where event notification will fire. Event scope is covered in the Recursive Events section of Event Registration.

Note Microsoft® Exchange runs each event sink notification on a unique out-of-process thread on the local machine.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Multiple Sinks

You can have multiple event sinks for the same event. The following illustration shows multiple events responding to a single event.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


OLE DB and ADO

You can use Exchange OLE DB (ExOLEDB) and Microsoft® ActiveX® Data Objects (ADO) to access data from within the event sinks. ExOLEDB is the Microsoft® Exchange 2000 Server OLE DB implementation for Exchange 2000 Server. ExOLEDB is a core component of Exchange and is registered automatically when Exchange 2000 Server is installed.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Events and Event Sink Interfaces

Microsoft® Exchange has defined interfaces that you can implement to handle synchronous events, asynchronous events, and system events. The following tables list the interfaces and their event methods. The subtopics in this section explain the concepts behind each interface and method.

Synchronous Events

Synchronous events occur before the item is committed to the store. The IExStoreSyncEvents has two methods, as shown in the following table.

Name | When the event is called (by Exchange)
OnSyncSave | When an item is saved to the store, before the changes are committed.
OnSyncDelete | When an item is deleted from the store, before the delete is committed.

Asynchronous Events

Asynchronous Events occur after the item is committed to the store. The IExStoreAsyncEvents has two methods, as shown in the following table.

Name | When the event is called (by the event sink source)
OnSave | When an item is saved to the store, after the changes are committed.
OnDelete | When an item is deleted from the store, after the delete is committed.

Note Other events, such as moving or copying an item, are handled by the save and delete events. When an item is copied in the store, it generates a save event. A move causes both the save and delete events.

System Events

The IExStoreSystemEvents has three methods, as shown in the following table.

Name | When the event is called (by the event sink source)
OnTimer | After a certain period of time.
OnMDBStartUp | When an MDB is started.
OnMDBShutdown | When an MDB is shut down.

For additional interfaces you can implement in the event sink, and interfaces you can use in the event sink, see Support Interfaces.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Synchronous Events

Synchronous events are processed in the context of an OLE DB transaction and occur before the item has been committed. Each synchronous event is called twice, once for the begin phase, and once for the commit or abort phase. The begin phase is called first, in prioritized order, for all qualifying sinks, then the commit or abort phase is called for the same sinks. Exchange waits for each synchronous event sink notification to finish before calling the next.

Microsoft® Exchange provides synchronous event notifications by calling the IExStoreSyncEvents interface methods shown in the following table.

Name | Description
OnSyncSave | Called before an item is saved to the Web Storage System.
OnSyncDelete | Called before an item is deleted from the Web Storage System.

While it runs, the synchronous event sink has exclusive control over the store Item that triggered the event. No other process or request can access the item until all event sinks have finished running.

To set the execution order of synchronous events, see Event Notification Priority.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Synchronous Event Details

The following information is important to know when you develop synchronous event methods:

  • Moving a folder does not cause events to occur on any items in the folder.
  • Copying a folder causes events to occur on all items in the folder.
  • Deleting a folder does not cause events to occur on items (messages and documents) in the folder. However, it causes events to occur on the subfolders.
  • Synchronous events are processed in a specific order.
  • The item causing the event is passed into the sink in the context of an OLE DB local transaction.
  • An item passed to a synchronous event sink transaction does not exist in the Web Storage System until the transaction has been committed.
  • When the event sink is processing a synchronous event, it can abort the OLE DB local transaction. If the transaction is aborted, no further synchronous event notifications occur for this event. Also, the synchronous events in this transaction that have already been notified (processed) are again notified that the transaction was aborted (the abort phase). This notification allows you to clean up data or undo activities if the event is aborted. For example, the method that handles the synchronous OnSyncSave event may create an associated file outside the Web Storage System. Upon notification of failure, your method could delete that external file.
  • Aborting the transaction associated with a delete event prevents the item from being deleted. If you abort an event that is the result of a move, both the save and delete steps of the move are aborted. This means that the original item is not deleted and the new item is not saved.

The following graphic illustrates how event sinks affect a Web Storage System item.

Event Sink Sequence for a Web Storage System Item

  1. The event occurs in the store.
  2. A " transaction" image of the item is created.
  3. Synchronous event methods receive event notification of the begin phase, in which they modify the image.
  4. The image is committed to the store as the item (from the OLE DB transaction).
  5. Synchronous event methods receive event notification of the commit phase.
  6. Asynchronous interface methods in sink classes receive notifications. The store item is directly modified.

    Note Asynchronous events are processed in no specified or guaranteed order. The event source does not wait for asynchronous events to finish.

As the previous illustration shows, synchronous events are always called twice—once for the begin phase, and once for the commit or abort phase. It is important to add code in your methods for handling synchronous events to determine which type of call is being made. The filter in an IExStoreSyncEvents::OnSyncSave method could look like the following example:

C++

if( lFlags & EVT_SYNC_BEGIN ) {
    Log(pLog,"-----------EVT_SYNC_BEGIN-----------\r\n");
    //Handle the sink here.
}
else if( lFlags & EVT_SYNC_COMMITTED ) {
    Log(pLog,"---------EVT_SYNC_COMMITTED---------\r\n");
    //Handle the commit here.
}
else if( lFlags & EVT_SYNC_ABORTED ) {
    Log(pLog,"----------EVT_SYNC_ABORTED----------\r\n");
    //Handle the abort here.
}

For a Support Interface that allows you to save data between the begin phase and the commit or abort phase of an event, see IUserData.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Asynchronous Events (Notifications)

An asynchronous event is essentially a notification that an event occurred.

Microsoft® Exchange provides asynchronous event notifications by calling the IExStoreAsyncEvents interface methods shown in the following table.

Name | Description
OnSave | Called when an item is saved to the Web Storage System.
OnDelete | Called when an item is deleted from the Web Storage System.

When you process an asynchronous event, Exchange processes the return value. Returning S_OK indicates that the event notification was handled successfully . Returning S_PENDING indicates that you are handling the Exchange notification in a separate process. When you return S_PENDING, you must notify Exchange (from the separate process) when you have finished handling the Exchange by calling IAsyncNotify Completed.

See IAsyncNotify Interface for information on processing asynchronous events in a Component Object Model (COM) object.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Asynchronous Event Details

The following list presents conceptual details about asynchronous events:

  • Asynchronous events do not have any firing priority.
  • Moving a folder does not cause events to fire on any items in the folder.
  • Copying a folder causes events to fire events on all items in the folder.
  • Deleting a folder does not cause events to fire on items (messages and documents) in the folder. However, it causes events to fire on the subfolders.
  • When the OnDelete event is called, the item has already been deleted.
  • There is no guarantee as to how soon asynchronous event notifications are called after the event occurs.
  • Asynchronous events are not processed if a synchronous event aborts the asynchronous event.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


System Events

System events give timed notifications or notify the event sink that databases have started up or shut down.

Microsoft® Exchange provides system event notifications by calling the IExStoreSystemEvents interface methods shown in the following table.

Name | Description
OnTimer | Called after a certain period of time.
OnMDBStartUp | Called when a MDB is started.
OnMDBShutDown | Called when a MDB is shut down.

Exchange runs each system event notification in a separate process. Exchange does not wait for the notification process to finish. System events do not lock items in the store.

You can use timer events for repeated calls, such as scheduling routine tasks. They can also be used for a one-time event.

System events are not tied to a particular item or location in the store (scope). However, where you save the OnTimer event registration can provide a context in the event notification. For example, you may want to perform periodic checking on items in a specific folder. You place the OnTimer event registration in that folder so that when the event method is called, you know where to perform the checking tasks.

Related Topics

  • Event Registration
  • Contextual Information in an Event Registration

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Additional Event Sink Interfaces

You can implement additional interfaces in the event sink to have further control over the registration for events in your sink. You do not register for the event system to call these methods. If the interface methods are implemented in your sink, they are automatically called at the appropriate times.

ICreateRegistration

The optional ICreateRegistration interface method shown in the following table is called by the event sink source.

Name | Description
Register | Called by Microsoft® Exchange when an event registration item is saved copied, moved, or replicated. Use this method to reject event registration requests, or respond registration items that have been modified, moved, copied, or replicated.

Whenever an event registration item that specifies the event sink is saved, copied, moved, or replicated, Exchange automatically queries the event sink for this interface. This gives you an opportunity to perform your own custom checks for event registration and handle event registrations when they are changed, copied, moved or replicated.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Support Interfaces

Some support interfaces exist for you to work with event sinks. Some interfaces are for use within an event, and others are for use when registering events.

Some interfaces are for use in an event sink. They allow you to access sink-related store information and perform tasks in the store. Some of these interfaces are passed as arguments in the event method calls. In all cases, the interfaces can be obtained from Microsoft® Exchange objects. You do not need to implement them.

The following tables describes available support interfaces.

Name | Description
IAsyncNotify | Allows an asynchronous event handler to notify Exchange that it has finished processing an event.
IExoledbUrlMapper | Methods for converting paths to different types.
IExStoreEventInfo | Used to retrieve event information and control the event transaction (passed to every method that the store calls for event sink notification).
IExStoreDispEventInfo | OLE Automation-compatible version of the IExStoreEventInfo.
IExStoreEventLogonInfo | Used to provide information about the user who caused the event, and the store in which the event occurred.
IExStoreEventRegistrationURL | Returns the URL of the event registration item.
IGetSourceURL | Used for getting the URL of the source row.
IStoreGUIDFromURL | Gets the MDB globally unique identifier (GUID) from the given URL (cocreatable).
IUserData | Used as a temporary place to persist data for the duration of the synchronous event (from the begin phase to the commit or abort phase).

The use of these interfaces in an event sink is covered in Information Passed to an Event Method.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Event Registration

You must register with Microsoft® Exchange to receive event notifications by creating and saving Event Registration Items. This section addresses the concepts behind event registration.

The Event Registration Item

Registration Steps

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


The Event Registration Item

An item becomes an event registration item when you set the content-class to urn:content-class:storeeventreg.

The following defines the event properties for an Event Registration item:

" http://schemas.microsoft.com/exchange/events/" namespace.

Property | Required? | Use
Criteria | No | A Structured Query Language (SQL) Where clause that specifies the conditions that will cause the event to fire.
Enabled | No | Boolean to enable the event to be fired.
EventMethod | Yes | Defines which event or events cause notification.
MatchScope | No | Defines where the event will fire relative to where it is saved.
Priority | No | The priority of the event.
ScriptUrl* | Yes | The name of the script if the event is a script being run by the Script Host Sink.
Sinkclass | Yes | The class identifier (CLSID) or progID of the object containing the event sink.
TimerExpiryTime** | No | Time to end an OnTimer event.
TimerInterval** | Yes | Interval, in minutes, for an OnTimer event.
TimerStartTime** | Yes | Start time for an OnTimer event.

*Required only if using a script to handle the event.

**Used only for OnTimer event.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Registration Steps

To register to receive notification of specific events:

  1. If the event sink is a Component Object Model (COM) class (not a script), you must register it in the Microsoft® Windows® operating system.
  2. Create a store item with a content class of urn:content-class:storeeventreg. (It is now an event registration item.)
  3. Set properties on the item.
  4. Save the item to the store location where you want to keep the event notifications. (The registration is now complete.)

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Recursive Events

You save the event registration item to where you want to store event notifications. For synchronous events and asynchronous events, you further specify what items the event covers (items, folders, children). When an event sink is registered for a folder and its subfolders, it is called a recursive event.

Recursive Event Scope

You can register for recursive events only in Top-Level Folders. (Top-Level Folders have no parent in the MDB.)

Permissions for the event sink to handle recursive events are determined only for the folder in which the event is registered. This means that if you have rights to register and receive notifications for events in the parent folder, you can receive notification in all child folders. Manage the folder hierarchy so that child folders are created only in parent folders with trustworthy recursive events. You can perform additional checks during event registration and by checking the context of the event notification when handling the event.

To register for a recursive event scope, the application must save the event registration item to the root folder from which the sink is to recur. The application must also set the item property, "http://schemas.microsoft.com/exchange/events/MatchScope", to "DEEP". For details on this property, see The Event Registration Item.

Note If you register for a recursive event scope, use criteria to specify whether you want the event to fire on folders, items, or both.

Related Topics

  • Event Notification Priority
  • Registering for an Asynchronous Event Sink
  • Registering for MDB-Wide Events

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Registering for MDB-Wide Events

Global events can only be registered in the following folders:

For private mailbox stores:

File://./backofficestorage/ADMIN/%userdnsdomain%/MBX/SystemMailbox{GUID}/Storeevents/GlobalEvents

For public folders:

File://./backofficestorage/ADMIN/%userdnsdomain%/Public Folders/Non_ipm_subtree/StoreEvents{GUID}/GlobalEvents

Global events can be registered only by an Administrator, a member of the Domain Administrators group, or users in the Microsoft® Exchange Administrators role. It is not enough to be a member of the Administrators group or the Exchange Server group. Use the Exchange Administration Delegation Wizard in the Exchange Management console to make a user an Exchange Administrator.

The following code registers for a private MDB-wide event:

dim igetSG
dim regURL
dim WshShell
dim Return

set igetSG=CreateObject("Exoledb.StoreGuidFromUrl.1")
'Get the guid for the registration process
guid = igetSG.StoreGuidFromUrl("file://./backofficestorage/" + Anystoreitem)
'Anystoreitem is just that, any store item in the store will get you the 'store url. It might be something like:
'   "theserver.microsoft.com/MBX/user1/inbox"

'Build the registration URL (using "theserver.microsoft.com")
regURL = "file://./backofficestorage/ADMIN/theserver.microsoft.com/MBX/SystemMailbox" & guid & "/StoreEvents/GlobalEvents/my_event"

set WshShell=WScript.CreateObject("WScript.Shell")
Return = WshShell.Run ("cscript c:\regevent.vbs add onsyncsave mysink.sink " & regURL & " -m ANY", 4 , TRUE)

WScript.Echo Return
Note Server-wide events are not supported

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Event Notification Priority

When registering for synchronous event notifications, you set a priority that dictates when the notification will occur relative to the other event registrations waiting on the same event. The registration priority can have any value in the ranges shown in the following table.

Priority | Integer value | Hex value
Highest (first to be notified) | 0 | 0
Default | 65535 | 0x0000ffff
Lowest (last to be notified) | 2147483647 | 0x7fffffff

event registrations with the same priority can fire in any order.

The following depicts synchronous sink execution by priority.

Register the priority using the decimal value.

Priorities do not apply to asynchronous event registrations.

Recursive Sink Firing Order

Recursive event notifications occur before event notifications in the subfolders.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


The RegEvent Script

The Microsoft® Exchange 2000 Server documentation provides a useful script that you can use to register, enumerate, and delete event registrations. The Microsoft® Visual Basic® Scripting Edition (VBScript) code may also prove useful for you in developing your own registration scripts.

Running the RegEvent.vbs with no arguments returns the parameters as well as examples of use. The following defines the parameters for the RegEvent.vbs script.

cscript RegEvent.vbs Add|Delete|Enum
                             EventMethod
                             SinkClass
                             Registration Item Name(Scope)
                             StartTime
                             Interval
                             [-p Priority]
                             [-m MatchScope]
                             [-f CriteriaFilter]
                             [-file ScriptFilePath]
                             [-url ScriptUrl]
                             [-e ExpiryTime]

EventMethod (Add)

The name of the store or system event should be one or more of the following:

OnSave, OnDelete, OnSyncSave, OnSyncDelete, OnMdbStartup, OnMdbShutDown, or OnTimer.

Case is ignored. Multiple events can be specified in the same registration by placing semicolons (;) between the names of each event, for example, "OnSave;OnDelete".

SinkClass (Add)

The class identifier (in registry format) or programmatic identifier (Prog ID) of your event sink; for example, "MySinks.SaveSink.1".

Registration Item Name (Add|Delete|Enum)

The name of the event registration item. The event scope is defined by where you save it; for example, file://./backofficestorage/domain/public%20folders/myfolder/EventRegItem1 registers for events in "myfolder".

StartTime (OnTimer)

When to start the OnTimer event, for example: "8/4/98 01:50:00 AM".

Interval (OnTimer)

The time, in minutes, between each OnTimer event notification.

Priority (Add for OnSyncSave and OnSyncDelete)

[optional] The registration’s priority. See Event Notification.

MatchScope (add for synchronous and asynchronous notifications)

[optional] The scope for the Event Registration. Can be one of the following: DEEP | SHALLOW | EXACT | ANY. Defaults to EXACT.

CriteriaFilter (Add)

[optional] An SQL WHERE clause of conditions for notification. For example, WHERE "DAV:ishidden" = FALSE. See “Remarks,” later in this topic.

ScriptFilePath (Add)

[optional] The full file path to the event sink script file. If a script host is specified (by the sinkclass progid or clsid) then ScriptFilePath points to a script file in the file system.

ScriptUrl (Add)

[optional] The full HTTP URL to the event sink script file. If a script host is specified (by the sinkclass progid or clsid), ScriptURL points to a script in the Web Storage System.

ExpiryTime (OnTimer)

[optional] When to stop the OnTimer event; for example: "8/4/99 01:50:00 AM".

Remarks

Exchange must be running for you to create event registrations.

You cannot register for the OnTimer event with any other events.

You cannot register for system events and synchronous or asynchronous events in the same command. (For example, "Regevent Add OnSave;OnMDBStartup" is not allowed.)

For parameter definitions and examples of each call you can make with regevent.vbs, see Managing Event Registrations With RegEvent.vbs.

For details on the CriteriaFilter, see information on the criteria property of The Event Registration Item.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Event Registration Guidelines

The scope of a sink is restricted to a single MDB.

Event registration items are automatically hidden when saved.

Event sinks in a dynamic-link library (DLL) need to have a surrogate host defined for when they are instantiated by Microsoft® Exchange. Wrapping the DLL in a COM+ Application assigns the surrogate host automatically.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Event Registration Security

To register for an event, the user saving the event registration item must be a member of the Folder Owner role for the folder in which the event registration is saved.

You can also implement the ICreateRegistration::Register method in the event sink. This method gives you a programmatic means to evaluate and abort event registration requests. For more information, see Additional Sink Interfaces.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Event Registration Modification

You change event registrations by modifying and saving the original event registration item.

Enumerating Event Registrations

Event registrations can be enumerated programmatically or by using the regevent.vbs script. For an example of programmatic enumeration of event registrations, see Enumerating Event Registrations for a Folder.

Deleting an Event Registration

An event registration is removed by deleting the event registration item. Deleting a folder removes all event registrations in the folder and the folder's subfolders.

Moving or Copying an Event Registration

If you move or copy an event registration, it will automatically register in the new location.

Stopping or Starting an Event Registration

To stop an event registration from providing notification without deleting the registration, set the event registration item's enabled property to false.

Setting the enabled property to true will start the event registration again.

Related Topics

  • The Event Registration Item

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Event Reliability

Both synchronous and asynchronous event notifications are reliable under normal conditions. That is, no notification is skipped on an event. However, if there is a failure in the store, Exchange might call your event method multiple times. For example, Microsoft® Exchange might shut down after three of five event notifications have been invoked. When Exchange restarts, the three previous event notifications might or might not be invoked a second time. An event method that fails after being notified will not be notified again for that specific event.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Working in an Event Sink

Developing code in an event sink depends on several key concepts. The following topics cover those concepts:

Loop Recursion

Information Passed to an Event Method

Contextual Information in an Event Registration

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Loop Recursion

An asynchronous event method can modify the item that caused the event notification. This, in turn, can fire an event for the same item, thereby causing a recursive event loop. The event sink must ensure that looping does not occur.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Information Passed to an Event Method

Microsoft® Exchange passes information to the event methods through the event notification. Interfaces are passed into the event sinks, and other interfaces can be obtained from within the event sink. For a list of interfaces that you can obtain from within an event sink, see Support Interfaces.

The event methods that handle synchronous events receive the IExStoreEventInfo Interface and an image of the item that caused the event to fire. For more information, see Synchronous Events Details.

The event methods that handle asynchronous events receive the IExStoreEventInfo Interface and the URL of the item that caused the event to fire. For more information, see Asynchronous Events Details.

The OnTimer event method receives the URL for the event registration item.

The OnMDBStartUp and OnMDBShutDown methods receive the MDB GUID and MDB name.

It is possible to pass custom information from the event registration item to the event sink. For more information, see Contextual Information in an Event Registration.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Contextual Information in an Event Registration

This topic assumes an understanding of event registration.

You can store contextual information in custom properties on the Event Registration Item. Information properties can include event location, users the event is for, a search query needed to notify users of an event, and so on.

Event methods can retrieve these properties by accessing the event registration item through the IExStoreDispEventInfo.EventRecord property, which points to the registration item.

To pass custom data from the event registration item to the event sink:

  1. Add custom properties at registration to the event registration. Use Fields.Append to do this.
  2. Retrieve the custom properties from the event item in the event sink. Use the Fields("<property name>") method to retrieve the property values.
Note You can change the properties in the event registration item from within the event sink.

Related Topics

  • Setting and Retrieving Custom Properties

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Security in an Event Sink

Synchronous events can obtain an OLE DB session object from the IExStoreEventInfo interface that is passed to the method handling the event in the sink. This provides a session logged on as the user who caused the event to occur. Therefore, the event sink has access to the event item, the mailbox, or the public folder in which the event occurred, and any items in the MDB in which the event occurred that the logon has access to.

Note Logons are scoped within sessions and therefore cannot access more than one store. Therefore, a synchronous sink handling an item in a public folder does not have access to the mailbox of the user who caused the event.

The OnTimer event has neither context nor scope.

See the following subtopic for information on how to change the security context:

COM+ Applications

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


COM+ Applications

You can wrap the event sink, which is a Component Object Model (COM) class, in a COM+ application (previously called an MTS package). A COM+ application can provide a user context for the event to run in. This is advantageous because the event may now access the store with the privileges of the package's security context without having to log on.

Note COM+ application wrappers can have only one security context per registered sink class. In cases where the same sink class requires different security contexts, you can wrap the sink class multiple times and register each wrapped class as different sink class.

One Microsoft® Exchange 2000 Server object that typically must be wrapped by a COM+ application package is the Script Host Sink.

It is also possible to create COM+ applications that run at startup. In some cases this can be useful for initialization purposes.

Additional Security Restrictions

Individual event sinks can enforce additional security restrictions by employing COM+ role-based security at the component, interface, or method level. See "Security in COM+" in the COM+ section of the Platform SDK in the MSDN® Library.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


The Script Host Sink

The Script Host Sink is provided and registered with Microsoft® Exchange 2000 Server for running all event methods in scripts. The Script Host Sink runs the scripts in process. To run a script, you specify the Script Host Sink as the event sink class and then specify the script in the event registration item's ScriptUrl property.

For an explanation of how to properly name the event methods in scripts, see Event Naming.

The Script Host resides in exodbesh.dll. It is not automatically registered with the installation of Exchange. It should be registered on the server by an administrator. The typical registration name is ExOleDB.ScriptEventSink.1.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Event Naming

In Component Object Model (COM) class event sinks, you name event methods by prefixing the event name with the interface name. Use the following event method names:

IExStoreSyncEvents_OnSyncSave
IExStoreSyncEvents_OnSyncDelete
IExStoreAsyncEvents_OnSave
IExStoreAsyncEvents_OnDelete
IExStoreSystemEvents_OnMDBStartUp
IExStoreSystemEvents_OnMDBShutDown
IExStoreSystemEvents_OnTimer

For example, the OnSave event method is declared as follows:

Private Sub IExStoreAsyncEvents_OnSave (pEventInfo,URLItem,Flags)
  'sink code
End Sub

In Microsoft® Visual Basic®, you can use the Implements declaration to specify that you are going to implement methods in a Visual Basic class. The following code declares the interfaces:

Implements IExStoreAsyncEvents
Implements IExStoreSyncEvents
Implements IExStoreStoreEvents

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Event Naming in Scripts

To implement event methods in scripts, prefix all event methods with "ExStoreEvents_" as shown in the following table.

ExStoreEvents_OnSyncSave
ExStoreEvents_OnSyncDelete
ExStoreEvents_OnSave
ExStoreEvents_OnDelete
ExStoreEvents_OnMDBStartUp
ExStoreEvents_OnMDBShutDown
ExStoreEvents_OnTimer

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Sink Monitoring

Event sinks can be monitored. The following topics cover event sink monitoring:

Event Logs

Performance Monitor Counters

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Event Logs

The Microsoft® Exchange OLE DB provider logs events in the Microsoft® Windows® 2000 Application event log. Those events are shown in the following table.

Severity | Symbol | Description
Error | EVENTS_BINDING_DISABLED | Exchange OLE DB (ExOLEDB) has disabled the event registration due to the problems in the event sink.
Error | EVENTS_INVALID_BINDING | ExOLEDB was unable register the event.
Error | EVENTS_INVALID_CRITERIA_FILTER | ExOLEDB was unable to process the specified event criteria filter.
Error | EVENTS_INVALID_PROPERTY_VALUE | ExOLEDB was unable to initialize the event registration.
Error | EVENTS_INVALID_SINK_CLASS | ExOLEDB was unable to either create an event sink object or get the necessary interface or interfaces from the sink class.
Error | EVENTS_MISSING_PROPERTY | ExOLEDB was unable to initialize event registration due to a missing property value.
Error | EVENTS_UNABLE_TO_INITIALIZE_SOURCE | ExOLEDB was unable to initialize event registration for the store.
Error | EVENTS_UNABLE_TO_REGISTER_BINDING | ExOLEDB was unable to initialize an event registration.
Error | EXOLEDB_FAILED_TO_REGISTER_OBJECTS | ExOLEDB was unable to successfully register event sink Component Object Model (COM) objects.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Performance Monitor Counters

System Monitor counters are fully supported for each event. For the core OLE DB functions, these counters are the same as the store counters. For Microsoft® Exchange-specific implementations, such as the various event interfaces, the OLE DB layer in the store supports counters for discovering how an out-of-process sink affects the performance of the overall system. In addition, the OLE DB provider creates counters for each virtual server instance. This is similar to what is done by other Microsoft Internet Information Services (IIS), such as SMTP, Network News Transport Protocol (NNTP), and HTTP services.

Each event (for example, OnSyncSave) appears as an instance of the following counters (all rate counters are per second):

  • Submitted Rate
  • Submitted Total
  • Completed Rate
  • Completed Total

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Using Property and Full-Text Indexing

You can improve search performance by implementing full-text indexing and by creating indexes for properties you define in the Web Storage System.

This section consists of the following topics:

Property Indexing

Full-Text Indexing

Customizing Full-Text Indexing

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Property Indexing

You can create indexes on custom properties using schema.

To create an index on a custom property:

  1. Set the property definition urn:schemas-microsoft-com:exch-data:isindexed to TRUE. (This setting alone does not create the index.)
  2. Define a content class that includes the custom property.
  3. Include that content class in a folder’s expected content class. This folder is typically the application folder containing the items that hold your data.
  4. Use CREATE INDEX to create indexes on all properties that are defined in the folder’s expected content class. (This function indexes all items in a folder rather than individually.)

The indexed property is now quickly accessible by Structured Query Language (SQL) queries.

Note Indexes cannot be created in the installable file system M: drive. Indexes cannot be created on properties of the existing default Web Storage System namespace, such as the DAV: Namespace.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Full-Text Indexing

By implementing full-text indexing, you can do fast full-text searches by using the CONTAINS and FREETEXT predicates in a Structured Query Language (SQL) query. The full-text indexing process indexes words in message and document bodies and additionally indexes words within message properties of the urn:schemas:mailheader: Namespace. Full-Text indexing also enables Microsoft® Outlook® users to search for documents as well as messages. Non-binary attachments are also indexed.

To implement full-text indexing, use the Microsoft® Exchange System manager to navigate to the store to be indexed. Right-click on the store and click Create Full-Text Index. After you create the index, you can specify options on the Full-Text Indexing tab of the store’s Properties to set the update interval, type of population, and other settings. For more information about using full-text indexing, see Exchange System Manager help.

Full-text indexing creates indexes on words in the bodies of the following document types: .doc, .xls, .ppt, .html, .htm, .asp, .txt, and .eml.

Full-text indexing creates search catalogs for use by the search engine; however, there is no programmatic way to manipulate search catalogs in the Web Storage System.

The properties that participate in full-text indexing are listed in the following table. The first parameter of the CONTAINS and FREETEXT predicates allow you to include searching the content in one or all of these properties in addition to searching the message or document body.

MAPI Properties | urn:schema:httpmail:properties
PR_SUBJECT, PR_SUBJECT_W | urn:schema:httpmail:subject
PR_BODY, PR_BODY_W | urn:schema:httpmail:textdescription
PR_SENDER_NAME, PR_SENDER_NAME_W | urn:schema:httpmail:sendername
PR_SENT_REPRESENTING_NAME, PR_SENT_REPRESENTING_NAME_W | urn:schema:httpmail:fromname
PR_DISPLAY_TO, PR_DISPLAY_TO_W | urn:schema:httpmail:displayto
PR_DISPLAY_CC, PR_DISPLAY_CC_W | urn:schema:httpmail:displaycc
PR_DISPLAY_BCC, PR_DISPLAY_BCC_W | urn:schema:httpmail:displaybcc
PR_SENDER_EMAIL_ADDRESS, PR_SENDER_EMAIL_ADDRESS_W | urn:schema:httpmail:senderemail

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Customizing Full-Text Indexing

You can add properties to participate in full-text indexing and add or remove noise words that are excluded in a search.

Note Non-Searchable Properties cannot be full-text indexed because they are calculated.

Adding Properties

If you are familiar with adding keys to the Microsoft® Windows® registry, you can set up other properties to be full-text indexed in addition to the urn:schemas:httpmail: Namespace properties listed in Full-Text Indexing. You create a text file of properties that referred to in the registry by the following key:

HKEY_LOCAL_MACHINE\Software\Microsoft\Search\1.0\ExchangeParameters\SchemaTextFilePathName

To add properties for full-text indexing

  1. Create a text file of a list of properties you want to be full-text indexed. The full name for each property must on a separate line.
  2. Start the Registry Editor by entering regedt32 at a command prompt.
  3. Activate the HKEY_LOCAL_MACHINE window.
  4. Navigate to the key Software\Microsoft\Search\1.0.
  5. If it does not already exist, add a key under 1.0 with the name ExchangeParameters.
  6. Under Exchange Parameters, add a value with the name SchemaTextFilePathName, a data type of REG_SZ, and a string value of the path to the text file of properties, such as "E:\Exchsrvr\fulltextprops.txt."
  7. Close the registry editor.

The properties will be full-text indexed the next time full-text indexing is run as configured in the Microsoft® Exchange System Manager.

Editing Noise Words

Noise words are words that the MsSearch engine excludes from a full-text search, such as “but” and “or.” Noise word files are in the \Program Files\Common Files\System\MSSearch\Data\Config folder on the Exchange 2000 Server. There are noise words for different languages, and the English noise word is noise.eng.

You can add or remove noise words in these files. The changes won’t take effect until the next time full-text indexing is run.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Appendixes

This section contains the following appendix topic for the Web Storage System.

Namespace URLs and URNs

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Namespace URLs and URNs

A namespace is a Uniform Resource Identifier (URI), in the form of a character string, which is used to identify a resource on the Internet. The two most common URI schemes currently being used are the URL and the Uniform Resource Name (URN):

  • URL. An address for a resource on the Internet. Web browsers use URLs to locate Internet resources. A URL defines the protocol used to access the resource (such as http://), the host on which the resource is available, and path information required to access the resource on the host. For example: http://www.microsoft.com/default.asp is a URL.
  • URN. A name for a resource on the Internet. URNs uniquely identify (name) Internet resources, without regard to where they are located. As such, URNs are intended only to generate unique names and do not normally imply protocols, hosts, or path information.

Both URLs and URNs are forms of URIs.

With the Web Storage System, URLs are used both as URIs in item property names and to identify particular items. URNs are used only with property names. For example, an item's URL could be file://./backofficestorage/domain.tld/public folders/folder1/. That item will also have properties named http://schemas.microsoft.com/exchange/security/descriptor and DAV:contentclass. The first property name is composed of the namespace URI http://schemas.microsoft.com/exchange/security/ and the local name "descriptor". The second property name is composed of the namespace URI "DAV:" and the local name "contentclass".

Namespace URIs are commonly expressed using the URL scheme. However, the URL is used only to scope the local part of the property name and does not imply that a resource or item exists at this URL or that it can be downloaded.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Core Web Storage System Tasks

The topics in this section describe common Web Storage System tasks.

Working with Folders and Items

Working with Item Properties

Searching the Web Storage System

Using Schema

Security Tasks

Using Web Storage System Events

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Working with Folders and Items

The following sections describe how to work with items in the Web Storage System.

Accessing Folders and Items

Creating Folders

Creating Items

Copying Items

Deleting Items

Moving Items

Accessing Item Streams

Using Transactions

Visual C++ Samples

Note In the Web Storage System architecture, a folder is an item that is also a collection.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Accessing Folders and Items

The following task shows how to get an existing item in the Web Storage System. The example function performs the following steps:

  1. Attempts to bind to the item at this URL. If an error occurs, the function fails.
  2. Returns a reference to the Record object bound to the new item.

VBScript

<job id="getitem">
<reference object="adodb.record"/>
<script language="vbscript">

Dim Rec
Dim InfoNT
Dim sUrl
Dim sRelPath
Set InfoNT = CreateObject("WinNTSystemInfo")

sRelPath = "/public/test_folder/item1.txt"
sUrl = "http://" & InfoNT.Computername & sRelPath

Set Rec = getItem_rw(sUrl, Nothing)
WScript.echo "Opened " & Rec.Fields("DAV:displayname") & " at URL: " & Rec.Fields("DAV:href")
' ...

Dim Conn
Set Conn = CreateObject("ADODB.Connection")
Conn.Provider = "ExOLEDB.DataSource"
Conn.Open sUrl
Set Rec = getItem_ro(sUrl, Conn)
WScript.echo "Opened " & Rec.Fields("DAV:displayname") & " at URL: " & Rec.Fields("DAV:href")

''''''''''''''''''''''''''''''''''''''''''''''''''''
' getItem_rw
'   sUrl - The URL to the item (http).
'   Conn   - An open Connection object, or Nothing.
'
''''''''''''''''''''''''''''''''''''''''''''''''''''

Function getItem_rw( sUrl, Conn )

 Dim Rec
 Set Rec = CreateObject("ADODB.Record")

 ' Did caller pass a Connection object reference?
 If Not ( VarType(Conn) = vbObject AND TypeName(Conn) = "Connection" ) Then
   Set Conn = CreateObject("ADODB.Connection")
   Conn.Provider = "ExOLEDB.DataSource"
   Conn.Open sUrl
 End If

 ' Try to bind to the item.
 Rec.Open sUrl, Conn, adModeReadWrite

 Set getItem_rw = Rec

End Function

''''''''''''''''''''''''''''''''''''''''''''''''''''
' getItem_ro
'   sUrl - The URL to the item (http).
'   Conn   - An open Connection object, or Nothing.
'
''''''''''''''''''''''''''''''''''''''''''''''''''''

Function getItem_ro( sUrl, Conn )

 Dim Rec
 Set Rec = CreateObject("ADODB.Record")

 ' Did caller pass a Connection object reference?
 If Not ( VarType(Conn) = vbObject AND TypeName(Conn) = "Connection" ) Then
   Set Conn = CreateObject("ADODB.Connection")
   Conn.Provider = "ExOLEDB.DataSource"
   Conn.Open sUrl
 End If

 ' Try to bind to the item.
 Rec.Open sUrl, Conn

 Set getItem_ro = Rec

End Function
</script>
</job>

The following example demonstrates how to bind to an existing item using the native OLE DB interfaces directly when using Microsoft® Visual C++®. If the item is successfully bound, the OLE DB IRow interface address is returned.

C++

#include <oledb.h>
#include <msdasc.h>
#pragma comment(lib,"oledb.lib")
#pragma comment(lib,"msdasc.lib")

#define BUF_SIZE   4096

HRESULT getItem(BSTR url, IRow** ppRow)
{

   if(url == NULL)
      return E_INVALIDARG;

   HRESULT         hr            =  S_OK;
   IBindResource*   pBRes         =  NULL;
   IUnknown*      pUnk         =  NULL;
   DBBINDURLSTATUS dwBindStatus   = 0;
   CLSID         clsid_ExOLEDBProviderBinder;

   if(FAILED(hr = CLSIDFromProgID(L"ExOLEDB.Binder", &clsid_ExOLEDBProviderBinder)))
      return hr;

   hr = CoCreateInstance(
      clsid_ExOLEDBProviderBinder,
      NULL,
      CLSCTX_INPROC_SERVER,
      IID_IBindResource,
      (void**)&pBRes);

   if(FAILED(hr))
      return hr;

   hr = pBRes->Bind(
      NULL,
      url,
      DBBINDURLFLAG_READWRITE,
      DBGUID_ROW,
      IID_IRow,
      NULL,
      NULL,
      &dwBindStatus,
      (IUnknown**) &pUnk);

   if(FAILED(hr)){
      pBRes->Release();
      return hr;
   }

   hr = pUnk->QueryInterface(ppRow);
   pBRes->Release();
   return hr;

}

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Traversing Folders with ADO

Visual Basic

Note The following example uses a file URL with the Exchange OLE DB (ExOLEDB) provider. The ExOLEDB provider also supports the HTTP URL scheme. Using the HTTP URL scheme allows both client and server applications to use a single URL scheme.
'Traversing folders with ADO
'1.Create a new project in VB and Name it as project1.vbp
'2. Add a form named form1.frm
'3. Add a command button to the form name it as command1
'4. Add a list box to the form name it as list1
'5. Paste the code in the code window for the form form1
'6. Reference the project with CDO for Exchange 2000, ADO 2.5, and Active DS libraries
'7. Run the project

Private Sub Command1_Click()
Dim oRec As ADODB.Record
Dim sURL As String
Dim sSQL As String
Dim oRst As ADODB.Recordset
Dim sHREF As String
Dim sDomainName As String
Dim sLocalPath As String
Dim sMailBox As String
Dim oADSysInfo As ADSystemInfo

On Error Resume Next

Set oADSysInfo = CreateObject("AdSystemInfo")

sDomainName = oADSysInfo.DomainDNSName
sMailBox = "User1"
'specify a URL to the mailbox
sLocalPath = "MBX/" & sMailBox

Set oRec = CreateObject("ADODB.Record")
Set oRst = CreateObject("ADODB.Recordset")

sURL = "file://./backofficestorage/" & sDomainName & "/" & sLocalPath
oRec.Open sURL
If Err.Number = 0 Then
'create the SQL query for the recordset
sSQL = "select "
sSQL = sSQL & " ""urn:schemas:mailheader:content-class"""
sSQL = sSQL & ", ""DAV:href"""
sSQL = sSQL & ", ""DAV:displayname"""
sSQL = sSQL & " from scope ('shallow traversal of " & Chr(34)
sSQL = sSQL & sURL & """') "
sSQL = sSQL & " WHERE ""DAV:ishidden"" = false"

'open the recordset, a list of folder and/or items
oRst.Open sSQL, oRec.ActiveConnection
List1.Clear
List1.AddItem "Private Folders for " & sMailBox & ":"
Do While Not oRst.EOF
List1.AddItem " " & oRst.Fields("DAV:displayname")
oRst.MoveNext
Loop
Else
MsgBox "Could not open MailBox for : " & sMailBox
End If
oRst.Close

''Now for the public folders :
oRec.Close
Set oRec.ActiveConnection = Nothing
sURL = "file://./backofficestorage/" & sDomainName & "/Public Folders"
oRec.Open sURL

'create the SQL query for the recordset
sSQL = "select "
sSQL = sSQL & " ""urn:schemas:mailheader:content-class"""
sSQL = sSQL & ", ""DAV:href"""
sSQL = sSQL & ", ""DAV:displayname"""
sSQL = sSQL & " from scope ('shallow traversal of " & Chr(34)
sSQL = sSQL & sURL & """') "
sSQL = sSQL & " WHERE ""DAV:ishidden"" = false"

'open the recordset, a list of folder and/or items
oRst.Open sSQL, oRec.ActiveConnection
List1.AddItem "Public Folders :"
Do While Not oRst.EOF
List1.AddItem " " & oRst.Fields("DAV:displayname")
oRst.MoveNext
Loop
End Sub

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Accessing Public Folders with ADO

VBScript

Note The following example uses a file URL with the Exchange OLE DB (ExOLEDB) provider. The ExOLEDB provider also supports the HTTP URL scheme. Using the HTTP URL scheme allows both client and server applications to use a single URL scheme.
Accessing Public folders with ADO
Set the required permissions on Exchange 2000 Server and IIS

Instructions
1)  Create a folder named "test" in the web storage system
2)  Save the file in that folder
3)  Change the strLocalPath  and DomainName variables to reflect your mailbox and domain.
4)  Save the file.
5)  open internet service manager and browse to the "test"  folder
6)  right click and go to properties
7)  go to the "Directory Security" tab.
8)  Click on "Edit" button next to the "handshake" icon
9)  Uncheck "Anonymous Access"
10) check the "Digest Authentication" and "Integrated windows authentication" boxes
11) click ok
12) click ok
13) Load the asp in the browser.
-->

<HTML>
<HEAD>
<META NAME="GENERATOR" Content="Microsoft FrontPage 4.0">
<TITLE></TITLE>
</HEAD>
<BODY>

<% Dim Rec
Dim Rs
Dim strURL
Dim strQ

Dim DomainName
Dim strLocalPath

'specify your own domain
DomainName = "somedomain.microsoft.com"
'specify a URL to folder or item
strLocalPath = "public folders/publicfoldername"

Set Rec = CreateObject("ADODB.Record")
Set Rs = CreateObject("ADODB.Recordset")

'this URL is for a public folder
strURL = "file://./backofficestorage/" & DomainName & "/" & strLocalPath

Rec.Open strURL

'Construct the SQL query to run on the folder --
'To avoid confusion in escaping quotes,
'Chr(34)'s are used to delimit the URL

strQ = "select "
strQ = strQ & " ""urn:schemas:mailheader:content-class"" "
strQ = strQ & ", ""DAV:href"" "
strQ = strQ & ", ""DAV:displayname"" "
strQ = strQ & " from scope ('shallow traversal of "
strQ = strQ & Chr(34) & strURL & Chr(34) & "')"
strQ = strQ & " ORDER BY ""DAV:displayname"" "

Rs.Open strQ, Rec.ActiveConnection

Rs.MoveFirst

While Not Rs.EOF

   Response.Write Rs.Fields("DAV:displayname").Value & "</br>"
   Rs.MoveNext

Wend

Rs.Close
Rec.Close

%>

<p>
</BODY>
</HTML>
<!--

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Getting a List of Folders

This example demonstrates how to get a list of folders within a folder. When constructing the Structured Query Language (SQL) query, you must require that the DAV:isfolder property is TRUE and the DAV:ishidden property is FALSE in the WHERE clause. For example:

select "DAV:displayname", "DAV:contentclass", "DAV:href" from
scope('shallow traversal of "/myfolders/myfolder"')
where "DAV:ishidden" = False AND
      "DAV:isfolder" = True

Note that a relative url is used in the SCOPE portion of the SQL statement. Searches occur within the context of a connection to a particular public information store or private store. Therefore, you need not use the entire URL in the query. The path is relative to the root folder for a public information store, and "MBX" for a private store. The beginning forward slash is required. For example, the folder at the URL file://./backofficestorage/domain.tld/Public Folders/myfolders/myfolder can be referred to by using the relative url /myfolders/myfolder; the path is anchored from the Public Folders root public information store folder.

VBScript

Function getFolderList( sUrl, Conn )

 ' Did caller pass a Connection object reference?
 If Not ( (VarType(Conn) = vbObject Or VarType(Conn) = vbString) AND TypeName(Conn) = "Connection" ) Then
   Set Conn = CreateObject("ADODB.Connection")
   Conn.Provider = "ExOLEDB.DataSource"
   Conn.Open sUrl
 End If

 Dim Rs
 Set Rs = CreateObject("ADODB.Recordset")

 Dim sql
 sql = "select ""DAV:displayname"", ""DAV:contentclass"", ""DAV:href"" from"
 sql = sql & " scope('shallow traversal of """ & sUrl & """')"
 sql = sql & " where ""DAV:ishidden"" = False and ""DAV:isfolder"" = True"

 Rs.Open sql, Conn
 Set GetFolderList = Rs

End Function

C++

#import <msado15.dll> no_namespace

_RecordsetPtr getFolderList(bstr_t sFolderUrl, _ConnectionPtr Conn) {

   _RecordsetPtr Rs(__uuidof(Recordset));

   if(Conn == NULL) {
      Conn.CreateInstance(__uuidof(Connection));
      Conn->Provider = "ExOLEDB.DataSource";
      try {
         Conn->Open(sFolderUrl, bstr_t(), bstr_t(),-1);
      }
      catch(_com_error e) {
         // handle error or throw...
         throw e;
      }
   }

   bstr_t sQuery = "select \"DAV:displayname\", \"DAV:contentclass\", \"DAV:href\" from \"";
        sQuery += sFolderUrl;
        sQuery += "\" where \"DAV:ishidden\" = False And \"DAV:isfolder\" = True";

   try {
      Rs->Open(
            variant_t(sQuery),
            variant_t((IDispatch*)Conn, true),
            adOpenUnspecified,
            adLockUnspecified,
            -1);
   }
   catch(_com_error e) {
      // handle error or throw...
      throw e;
   }

    return Rs;

}

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Creating Folders

The following examples show how to create a folder in the Web Storage System. The function in each example performs the following steps:

  1. The function attempts to create a folder at this URL. If an error occurs, the function fails.
  2. If the function is successful, it sets the new folder's DAV:contentclass property to the value "urn:content-classes:folder".
  3. The function returns a reference to the Record object that is bound to the new folder.

VBScript

<job id="createfolder">
<reference object="adodb.record"/>
<script language="vbscript">

If WScript.Arguments.Count < 1 Then
 WScript.Echo "Usage: cscript createfolder.wsf URL [content class]"
 WScript.Quit
End If

Dim sUrl
Dim sContentClass
sUrl = WScript.Arguments(0)
sContentClass = WScript.Arguments(1)

Dim Rec
Wscript.Echo "Creating folder at URL: " & sUrl
Set Rec = CreateFolder(sUrl, sContentClass, Nothing)
Wscript.Echo "Succeeded."

Function CreateFolder( sUrl, sContentClass, Conn )

 Dim Rec
 Set Rec    = CreateObject("ADODB.Record")

 ' Did caller pass a Connection object reference?
 If Not ( VarType(Conn) = vbObject AND TypeName(Conn) = "Connection" ) Then
   Set Conn = CreateObject("ADODB.Connection")
   Conn.Provider = "ExOLEDB.DataSource"
   Conn.Open sUrl
 End If

 If sContentClass = "" Then
  sContentClass = "urn:content-classes:folder" ' The Default is urn:content-classes:folder.
 End If

 ' Try to create the folder

 Rec.Open sUrl, Conn, adModeReadWrite, adCreateCollection
 Rec.Fields("DAV:contentclass") = sContentClass
 Rec.Fields.Update

 Set CreateFolder = Rec

End Function
</script>
</job>

The following example creates a new folder by using the native OLE DB interfaces directly in Microsoft® Visual C++®.

#include <oledb.h>
#include <msdasc.h>
#include <comdef.h>

#pragma comment(lib,"oledb.lib")
#pragma comment(lib,"msdasc.lib")

#define BUF_SIZE   4096

HRESULT CreateFolder( BSTR url, IRow** ppRow )
{

   if(url == NULL)
      return E_INVALIDARG;

   HRESULT            hr            = S_OK;
   DWORD            dwBindStatus   = 0;
   IBindResource*      pBRes         = NULL;
   ICreateRow*         pCrRow         = NULL;
   CLSID            clsid_ExOLEDBProviderBinder;

   if(FAILED(hr = CLSIDFromProgID(L"ExOLEDB.Binder", &clsid_ExOLEDBProviderBinder)))
      return hr;

   hr = CoCreateInstance(
      clsid_ExOLEDBProviderBinder,
      NULL,
      CLSCTX_INPROC_SERVER,
      IID_IBindResource,
      (void**)&pBRes);

   if(FAILED(hr))
      return hr;

   hr = pBRes->Bind(
      NULL,
      url,
      DBBINDURLFLAG_READWRITE,
      DBGUID_SESSION,
      IID_ICreateRow,
      NULL,
      NULL,
      &dwBindStatus,
      (IUnknown**) &pCrRow);

   if(FAILED(hr)){
      pBRes->Release();
      return hr;
   }

   pBRes->Release();

   dwBindStatus         =   0;
   IRow*      pRow      =   NULL;
   wchar_t*   newUrl      =   NULL;
   hr = pCrRow->CreateRow(
      NULL,
      url,
      (DBBINDURLFLAG_READWRITE | DBBINDURLFLAG_COLLECTION ),
      DBGUID_ROW,
      IID_IRow,
      NULL,
      NULL,
      &dwBindStatus,
      &newUrl,
      (IUnknown**)&pRow
   );
   if(FAILED(hr)){
      pCrRow->Release();
      return hr;
   }

   *ppRow = pRow;
   pCrRow->Release();

   return hr;
}

Related Topics

  • Creating Items (WebDAV)
  • Creating Folders (WebDAV)

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Creating Folders (WebDAV)

To create folders using the WebDAV protocol, perform the following steps:

  1. Create a MKCOL WebDAV request. The request Uniform Resource Identifier (URI) for the command is the URI to the folder that you are creating.
  2. Optionally, set properties for the new folder by sending an XML body in the request. You format the XML the same way as when sending a PROPPATCH command. For example
    <d:propertyupdate xmlns:d="DAV:">
 <d:set>
   <d:prop>
    <d:displayname>Folder 1</d:displayname>
   </d:prop>
  </d:set>
</d:propertyupdate>

    When sending a request body with the MKCOL command, set the Content-Type header to "text/xml" and set the Content-Length header to the appropriate value.

  3. Send the request.
  4. If successful, the response status will be "201 Created".

The following example shows a typical MKCOL request:

MKCOL /pub2/folder1/folder2/ HTTP/1.1
Host: hostname
Content-Type: text/xml
Content-Length: XXX

<?xml version="1.0"?>
<g:propertyupdate xmlns:g="DAV:" >
    <g:set>
        <g:prop>
            <g:displayname>value</g:displayname>
        </g:prop>
        <g:prop>
            <f:myprop xmlns:f="urn:schemas-mydomain-tld:">Test</f:myprop>
        </g:prop>
    </g:set>
</g:propertyupdate>

The following example uses an instance of the Microsoft.XMLHTTP Component Object Model (COM) class to send a MKCOL protocol command to a Web Storage System server.

JScript

function createFolder( urisource, vXML ) {

 var Req = new ActiveXObject("Microsoft.XMLHTTP");
 Req.open("MKCOL", urisource, false);
 if(vXML != "") {
  Req.setRequestHeader("Content-Type","text/xml");
  Req.send(vXML);
 }
 else {
  Req.send();
 }
 return Req;

}

Related Topics

  • Creating Search Folders

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Creating Folders Using CDOEX

Visual Basic

Note The following example uses a file URL with the Exchange OLE DB (ExOLEDB) provider. The ExOLEDB provider also supports the HTTP URL scheme. Using the HTTP URL scheme allows both client and server applications to use a single URL scheme.
'Creating Folders using CDOEx
'This sample shows how to create all kind of outlook type Folders
'Make reference to Exchange 2000 and ADO 2.5 libraries
'Make reference to Active DS Typy Library

Private Sub Main()
Dim strDomainName As String
Dim strLocalPathOfParentFolder As String
Dim strNewFolderName As String
Dim strUser As String

strDomainName = GetDomainDNSName()
strUser = "user1"
strNewFolderName = "NewtFolder"

' Sample 1: Create a folder under "Deleted Items" folder to hold 'AppointmentItems'
' specify the path of the folder under which a folder to be created
strLocalPathOfParentFolder = "MBX/" & strUser & "/Deleted Items"

Call CreateFolder(strDomainName, strLocalPathOfParentFolder, strNewFolderName, "IPF.Appointment")

' Sample 2: Create a folder under 'Public Folders' to hold 'ContactItems'
strLocalPathOfParentFolder = "Public Folders"

Call CreateFolder(strDomainName, strLocalPathOfParentFolder, strNewFolderName, "IPF.Contact")

Unload Me
End Sub

'strFolderType Name
'
'MailItems IPF.Note
'ContactItems IPF.Contact
'AppointmentItems IPF.Appointment
'NoteItems IPF.StickyNote
'TaskItems IPF.Task
'JournalItems IPF.Journal
'
Private Sub CreateFolder(strDomainName As String, strLocalPathOfParentFolder As String, strNewFolderName, strFolderType As String)
Dim Rec As New ADODB.Record
Dim strFolderUrl As String

' specify the url to the new folder to be created
strFolderUrl = "file://./backofficestorage/" & _
strDomainName & "/" & strLocalPathOfParentFolder & "/" & strNewFolderName

' open Record
Rec.Open strFolderUrl, , adModeReadWrite, adCreateCollection

' specify the content-class
Rec.Fields("DAV:contentclass") = "urn:content-classes:folder"

' specify the OutlookFolder Type
Rec.Fields("http://schemas.microsoft.com/exchange/outlookfolderclass") = strFolderType

' update
Rec.Fields.Update

' close the Record
Rec.Close

' clean up
Set Rec = Nothing

If Err.Number = 0 Then
MsgBox "Good Job!"
End If

End Sub

Private Function GetDomainDNSName() As String
Dim Info As New ADSystemInfo
Dim strDomain As String
strDomain = Info.DomainDNSName

GetDomainDNSName = strDomain
End Function

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Creating Items

The following task shows how to create a non-collection item in the Web Storage System. The example function performs the following steps:

  1. Attempts to create the item at this URL. If an error occurs, the function fails.
  2. If successful, sets the new item's DAV:contentclass property to the value " urn:content-classes:item".
  3. Returns a reference to the Record object bound to the new item.

VBScript

<job id="createitem">
<reference object="adodb.record"/>
<script language="vbscript">

If WScript.Arguments.Count < 1 Then
 WScript.Echo "Usage: cscript createitem.wsf URL [content class] [content type [, file contents name]]"
 Wscript.Echo "For example:"
 WScript.Echo " cscript createitem.wsf ""http://server/path/item.txt"" """" ""text/plain; charset=iso-8859-1"" <filename>"
 WScript.Quit
End If

Dim sUrl
Dim sContentClass
Dim sContentType
Dim sFileName

sUrl = WScript.Arguments(0)
sContentClass = WScript.Arguments(1)
sContentType  = WScript.Arguments(2)
sFileName = Wscript.Arguments(3)

Dim Rec
Wscript.Echo "Creating item at URL: " & sUrl
Set Rec = CreateItem(sUrl, sContentClass, sContentType, sFileName, Nothing)
Wscript.Echo "Succeeded."
Wscript.Echo Rec.Fields("DAV:href")
WScript.Echo Rec.Fields("DAV:contentclass")
Wscript.Echo Rec.Fields("urn:schemas:mailheader:content-type")

Function CreateItem( sUrl, sContentClass, sContentType, sFileName, Conn )

 Dim Rec
 Set Rec    = CreateObject("ADODB.Record")

 ' Did caller pass a Connection object reference?
 If Not ( VarType(Conn) = vbObject AND TypeName(Conn) = "Connection" ) Then
   Set Conn = CreateObject("ADODB.Connection")
   Conn.Provider = "ExOLEDB.DataSource"
   Conn.Open sUrl
 End If

 If sContentClass = "" Then
  sContentClass = "urn:content-classes:item" ' The default content class is urn:content-classes:item.
 End If

 If sContentType = "" Then
  sContentClass = "application/octet-stream"
 End If

 ' Try to create the item

 Rec.Open sUrl, Conn, adModeReadWrite, adCreateNonCollection
 Rec.Fields("DAV:contentclass") = sContentClass
 Rec.Fields("urn:schemas:mailheader:content-type") = sContentType
 Rec.Fields.Update

 If Not sFileName = "" Then
  Set Stm = Rec.Fields(adDefaultStream).Value
  sContentType = LCase(sContentType)
  If InStr(sContentType, "text") > -1 Then
   Stm.Type = adTypeText
   pos = InStr(sContentType, "charset=") + 8
   wscript.echo pos
   If pos > 8 Then
     sCharset = Mid(sContentType, pos)
     wscript.echo "charset: " & sCharset
     Stm.Charset = sCharset
   Else
     Stm.Charset = "US-ASCII"
   End If
  Else
   Stm.Type = adTypeBinary
  End If

  Stm.LoadFromFile sFileName
  Stm.Flush
 End If

 Set CreateItem = Rec

End Function
</script>
</job>

The following example illustrates how to create a new non-collection item and get an existing item by using the native OLE DB interfaces directly in Microsoft® Visual C++®.

#include <oledb.h>
#include <msdasc.h>
#include <comdef.h>

#pragma comment(lib,"oledb.lib")
#pragma comment(lib,"msdasc.lib")

HRESULT CreateItem( BSTR url, IRow** ppRow )
{

   HRESULT            hr               =   S_OK;
   DWORD            dwBindStatus      =   0;
   IBindResource*      pBRes            =   NULL;
   ICreateRow*         pCrRow            =   NULL;
   ITransactionLocal*   pTrans            =   NULL;
   CLSID            clsid_ExOLEDBProviderBinder;

   if(FAILED(hr = CLSIDFromProgID(L"ExOLEDB.Binder", &clsid_ExOLEDBProviderBinder)))
      return hr;

   hr = CoCreateInstance(
      clsid_ExOLEDBProviderBinder,
      NULL,
      CLSCTX_INPROC_SERVER,
      IID_IBindResource,
      (void**)&pBRes);

   if(FAILED(hr))
      return hr;

   hr = pBRes->Bind(
      NULL,
      url,
      DBBINDURLFLAG_READWRITE,
      DBGUID_SESSION,
      IID_ICreateRow,
      NULL,
      NULL,
      &dwBindStatus,
      (IUnknown**) &pCrRow);

   if(FAILED(hr)){
      pBRes->Release();
      return hr;
   }
   pBRes->Release();

   hr=pCrRow->QueryInterface(IID_ITransactionLocal,(void**)&pTrans);
   if(FAILED(hr))
      pTrans = NULL;
   else
   {
      DWORD dwLevel = 0;
      hr = pTrans->StartTransaction(ISOLATIONLEVEL_UNSPECIFIED,0,NULL,&dwLevel);
   }

   IUnknown*  pUnk   = NULL;
   wchar_t* newUrl;
   hr = pCrRow->CreateRow(
      NULL,
      url,
      DBBINDURLFLAG_READWRITE,
      DBGUID_ROW,
      IID_IRow,
      NULL,
      NULL,
      &dwBindStatus,
      &newUrl,
      &pUnk
   );

   if(FAILED(hr)){
      if(pTrans != NULL) {
         pTrans->Abort(NULL,FALSE,FALSE);
         pTrans->Release();
      }
      pCrRow->Release();
      return hr;
   }

   hr = pUnk->QueryInterface(ppRow);

   hr = pTrans->Commit(FALSE, 0, 0 );
   pTrans->Release();
   pCrRow->Release();
   pUnk->Release();

   return hr;
}

Related Topics

  • Creating Items (WebDAV)
  • Creating Folders (WebDAV)

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Creating Items (WebDAV)

To create non-folder items using the WebDAV protocol, perform the following steps:

  1. Create a PUT or PROPPATCH WebDAV request. The request Uniform Resource Identifier (URI) for the command is the URI to the item that you are creating.
  2. When using a PUT command, set the Translate: HTTP header to the value "f" (false).
  3. When using a PUT command, send the stream for the item as the request body.
  4. When using a PROPPATCH command, send the values of the properties in the request body.
  5. Set the Content-Type: header to the appropriate value, for example "text/html; charset=\"iso-8859-1\"" or "text/xml".
  6. Send the request.
  7. If successful, the response status will be "201 Created".

The following code shows a typical PUT request:

PUT /pub2/folder1/folder2/item1.txt HTTP/1.1
Host: hostname
Translate: f
Content-Type: text/plain
Content-Length: 4

abcd

The following example uses an instance of the Microsoft.XMLHTTP Component Object Model (COM) class to send a PUT protocol command to a Web Storage System server.

JScript

function createItem( uri, vXML ) {

 var Req = new ActiveXObject("Microsoft.XMLHTTP");
 Req.open("PROPPATCH", uri, false);
 if(vXML != "") {
  Req.setRequestHeader("Content-Type","text/xml");
  Req.send(vXML);
 }
 else {
  Req.send();
 }
 return Req;

}

/*
** This example uses a PUT command to put the stream for an item.
** If the item does not exist, it is created.
*/
function putItemStream( uri, text ){
 var Req = new ActiveXObject("Microsoft.XMLHTTP");
 Req.open("PUT", uri, false);
 Req.setRequestHeader("Translate","f");
 if(text != "") {
  Req.setRequestHeader("Content-Type","text/plain");
  Req.send(text);
 }
 else {
  Req.send("");
 }
 return Req;

}

To create a folder item, use the MKCOL protocol command. For more information, see Creating Folders.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Copying Items

To copy an item from one location to another within the same store, use the Record.CopyRecord method. If you copy a folder, all items and subfolders are also copied. You cannot use the Record.CopyRecord method to copy items from one public information store or mailbox store to another.

VBScript

<job id="copy_item">
<reference object="adodb.record"/>

<script language='vbscript'>

Dim Rec
Dim Info
Dim InfoNT
Dim sUrlRoot
Dim sUrl
Dim sUrlDest
Set Info   = CreateObject("ADSystemInfo")
Set InfoNT = CreateObject("WinNTSystemInfo")

SUrlRoot = "http://" & InfoNT.Computername & "." & Info.DomainDNSName & "/public/"
sUrl     = sUrlRoot & "test_folder/test1.txt"
SurlDest = sUrlRoot & "test_folder2/test1.txt"

copyItem sUrl, sUrlDest, Nothing

Sub copyItem( sUrl, sUrlDest, Conn )

  Dim Rec

 ' Did caller pass a Connection object reference?
 If Not ( VarType(Conn) = vbObject AND TypeName(Conn) = "Connection" ) Then
   Set Conn = CreateObject("ADODB.Connection")
   Conn.Provider = "ExOLEDB.DataSource"
   Conn.Open sUrl
 End If

 Set Rec = CreateObject("ADODB.Record")

 Rec.Open sURL, Conn, adModeReadWrite
 Rec.CopyRecord ,sUrlDest

 Rec.Close

End Sub
</script>
</job>

C++

#import <msado15.dll> no_namespace
#import <cdoex.dll> no_namespace

void copyitem(bstr_t urlfrom, bstr_t urlto) {

   _RecordPtr Rec(__uuidof(Record));
   _ConnectionPtr Conn(__uuidof(Connection));
   Conn->Provider = "ExOLEDB.DataSource";
   cout << urlfrom << endl;
   try {
      Conn->Open(urlfrom, bstr_t(""), bstr_t(""),-1);
   }
   catch(_com_error e) {
      // handle error or throw...
      throw e;
   }

   try {
      Rec->Open(
               variant_t(urlfrom),
               variant_t((IDispatch*)Conn, true),
               adModeReadWrite,
               adFailIfNotExists,
               adOpenSource,
               bstr_t(""),
               bstr_t(""));
   }
   catch(_com_error e) {
      // handle error or throw...
      throw e;
   }

   try {
      Rec->CopyRecord(
            bstr_t(),
            urlto,
            bstr_t(),
            bstr_t(),
            (CopyRecordOptionsEnum)adMoveOverWrite,
            VARIANT_FALSE);
   }
   catch(_com_error e) {
      // handle error or throw...
      throw e;
   }
}

Related Topics

  • Copying Items (WebDAV)

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Copying Items (WebDAV)

To copy items using the WebDAV protocol, perform the following steps:

  1. Create a COPY WebDAV request. The request Uniform Resource Identifier (URI) for the command is the URI to the item that you want to copy.
  2. Set the Destination: HTTP header to the URI for the copied item.
  3. Send the request. The body of the request should be empty.
  4. If successful, the response status will be "201 Created."

The following example shows a typical COPY request:

COPY /pub2/folder1/folder2 HTTP/1.1
Destination: /pub2/folder1/folder3
Host: hostname

The following example uses an instance of the Microsoft.XMLHTTP Component Object Model (COM) class to send a COPY protocol command to a Web Storage System server.

JScript

function copyItem( urisource, urito ) {

 var Req = new ActiveXObject("Microsoft.XMLHTTP");
 Req.open("COPY", urisource, false);
 Req.setRequestHeader("Destination",urito);
 Req.send();
 return Req;

}

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Copying Public Folders Using ADO

VBScript

Note The following example uses a file URL with the Exchange OLE DB (ExOLEDB) provider. The ExOLEDB provider also supports the HTTP URL scheme. Using the HTTP URL scheme allows both client and server applications to use a single URL scheme.
'Copying public folders using ADO
-->

<!--
'Build Instructions
'Add the ASP file below to a new virtual directory under the wwwroot.
'Change the domain in the code to reflect your install.
'Make sure that there are public folders in the PF tree with the same names as listed in the code.
-->

<%@ Language=VBScript %>
<HTML>
<HEAD>
<META NAME="GENERATOR" Content="Microsoft Visual Studio 6.0">
</HEAD>
<BODY>
<%
Dim Rec
Dim strURL

Dim DomainName
Dim strLocalPath
Dim strDestination

' const for the ADO CopyRecord method
' const adCopyOverWrite = 1
' const adCopyNonRecursive = 2

'specify your own domain
DomainName = "nrnobledom2.extest.microsoft.com"

'specify a URL to the folder or item to copy
'in this example, a folder and its items are copied

strLocalPath = "PUBLIC FOLDERS/ProjectTrack"
strDestination = "PUBLIC FOLDERS/myfolder"

Set Rec = CreateObject("ADODB.Record")

' set the strURL to the location of the folders
strURL = "file://./backofficestorage/" & DomainName & "/" & strLocalPath
strDest = "file://./backofficestorage/" & DomainName & "/" & strDestination
' open the record
Rec.Open strURL

' copy the folder from the source location to the destination folder
 Rec.CopyRecord strURL,"file://./backofficestorage/" & DomainName & "/" & strDestination,,,adCopyOverWrite
' Rec.CopyRecord strURL,strDest,,,adCopyOverWrite

' close the record
Rec.Close

Response.write "adCopyOverWrite: " & adCopyOverWrite & "<BR>"
Response.write "adCopyNonRecursive: " & adCopyNonRecursive & "<BR>"
Response.write "strURL: " & strURL & "<BR>"
Response.write "strDest: " & strDest & "<BR>"
Response.Write "<BR><BR>All Done" & "<BR>"
%>
</BODY>
</HTML>
<!--

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Deleting Items

To delete an item from a folder, use the Record.DeleteRecord method. If you delete a folder item, all items within the folder are also deleted.

VBScript

<job id="delete_record">
<reference object="adodb.record"/>

<script language='vbscript'>

Dim Rec
Dim Info
Dim InfoNT
Dim sUrl
Set Info   = CreateObject("ADSystemInfo")
Set InfoNT = CreateObject("WinNTSystemInfo")

sUrl = "http://" & InfoNT.Computername & "." & Info.DomainDNSName & "/public/test_folder2/test1.txt"

deleteItem sUrl, Nothing

Sub deleteItem( sUrl, Conn )

  Dim Rec

 ' Did caller pass a Connection object reference?
 If Not ( VarType(Conn) = vbObject AND TypeName(Conn) = "Connection" ) Then
   Set Conn = CreateObject("ADODB.Connection")
   Conn.Provider = "ExOLEDB.DataSource"
   Conn.Open sUrl
 End If

 Set Rec = CreateObject("ADODB.Record")

 Rec.Open sURL, Conn, adModeReadWrite
 Rec.DeleteRecord

 Rec.Close

End Sub
</script>
</job>

Visual Basic

' Reference to Microsoft ActiveX Data Objects 2.5 Library
' Reference to Microsoft CDO for Exchange 2000 Library

Sub DeleteRecord( sUrl as String )

  Dim Rec As New ADODB.Record
  Dim Conn as New ADODB.Connection

  Conn.Provider = "ExOLEDB.DataSource"
  Conn.Open sURL

  Rec.Open sURL, Conn, adModeReadWrite
  Rec.DeleteRecord

End Sub

Related Topics

  • Deleting Items (WebDAV)

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Deleting Items Using a Recordset

To delete all items in a folder, you can use a Recordset object’s Delete method.

The following example deletes all the items in a folder, except for subfolders that are stipulated by a WHERE clause.

VBScript

<job id="delete_record">
<reference object="adodb.record"/>

<script language='vbscript'>

Dim Info
Dim InfoNT
Dim sFolderUrl
Dim sQuery
Set Info   = CreateObject("ADSystemInfo")
Set InfoNT = CreateObject("WinNTSystemInfo")

sFolderUrl = "http://" & InfoNT.Computername & "." & Info.DomainDNSName & "/public/test_folder2/"

' Delete all non-folder items from folder.
sQuery = "SELECT * FROM scope('shallow traversal of " & Chr(34) & sURL & Chr(34) & "')" & _
         " WHERE ""DAV:isfolder"" = FALSE"

Dim cItems
cItems = deleteItemsMatchSQL(sFolderUrl, sQuery, Nothing)
wscript.echo "Deleted " & cItems & " Items from " & sFolderUrl

Function deleteItemsMatchSQL( sUrl, sQuery, Conn )

 Dim Rs
 Dim cItems

 ' Did caller pass a Connection object reference?
 If Not ( VarType(Conn) = vbObject AND TypeName(Conn) = "Connection" ) Then
   Set Conn = CreateObject("ADODB.Connection")
   Conn.Provider = "ExOLEDB.DataSource"
   Conn.Open sUrl
 End If

 Set Rs = CreateObject("ADODB.Recordset")

 With Rs
   .Open sQuery, Conn
   .MoveFirst
   cItems = .RecordCount
   While Not Rs.EOF
   .Delete 1 ' Current record
   .MoveNext
   Wend
   .Close
 End With

 deleteItemsMatchSQL = cItems

End Function
</script>
</job>

C++

#import <msado15.dll> no_namespace
#import <cdoex.dll> no_namespace

void deleteitems(bstr_t url, bstr_t sqlCondition) {

   _RecordsetPtr Rs(__uuidof(Recordset));
   _ConnectionPtr Conn(__uuidof(Connection));
   Conn->Provider = "ExOLEDB.DataSource";

   bstr_t sqlStatement;
   sqlStatement = "select \"DAV:href\" from scope('shallow traversal of \"";
   sqlStatement += url;
   sqlStatement += "\"') ";
   sqlStatement += sqlCondition;

   try {
      Conn->Open(url, bstr_t(), bstr_t(),-1);
      Rs->Open(
               variant_t(sqlStatement),
               variant_t((IDispatch*)Conn, true),
               (CursorTypeEnum)-1,
               (LockTypeEnum) -1,
               -1
               );
   }
   catch(_com_error e) {
      // handle error or throw...
      throw e;
   }

   long numRec = Rs->RecordCount;
   cout << "Record count: " << numRec << endl;
   try {
      Rs->MoveFirst();
      for(long i = 1 ; i <= numRec;  i++ ) {
         Rs->Delete(adAffectCurrent);
         Rs->MoveNext() ;
      }
   }
   catch(_com_error e) {
      cerr << "Error deleting item using Recordset." << endl;
   }
}

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Deleting Items (WebDAV)

To delete items using the WebDAV protocol:

  1. Create a DELETE WebDAV request. The request Uniform Resource Identifier (URI) for the command is the URI to the item that you want to delete.
  2. Send the request. The body of the request should be empty.
  3. If successful, the response status will be "200 OK".

The following example shows a typical DELETE request:

DELETE /pub2/folder1/folder2 HTTP/1.1
Host: hostname
Content-Length: 0

The following example uses an instance of the Microsoft.XMLHTTP COM class to send a DELETE protocol command to a Web Storage System server.

JScript

function deleteItem( uri ) {

 var Req = new ActiveXObject("Microsoft.XMLHTTP");
 Req.open("DELETE", uri, false);
 Req.send();
 return Req;

}

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Deleting Items in the Mailbox Using ADO

VBScript

Note The following example uses a file URL with the Exchange OLE DB (ExOLEDB) provider. The ExOLEDB provider also supports the HTTP URL scheme. Using the HTTP URL scheme allows both client and server applications to use a single URL scheme.
'Deleting items in the mailbox using ADO
-->

<!--

'Build Instructions
'Save the file to a newly created virtual directory under the wwwroot.
-->

<HTML>
<HEAD>
<META NAME="GENERATOR" Content="Microsoft Visual Studio 6.0">
</HEAD>
<BODY>
<%

Response.Write "User: " & Request.ServerVariables("AUTH_USER") & "</BR>"
Dim Rec
Dim strURL

Dim DomainName
Dim strLocalPath

'If you have a reference to Microsoft ActiveX Data Objects 2.5 Library (msado15.tlb)
'comment out the following line as adModeReadWrite is defined in msado15.tlb
 const adModeReadWrite = 3

' specify your own domain
DomainName = "nrnobledom2.extest.microsoft.com"

' specify a URL to the folder or item to delete
strLocalPath = "MBX/User1/Inbox"

Set Rec = CreateObject("ADODB.Record")

' this URL is for the folder
strURL = "file://./backofficestorage/" & DomainName & "/" & strLocalPath

' need to open the record as read/write to be able to delete the record
Rec.Open strURL,,adModeReadWrite

' delete the record from the folder
' The record needs to be exactly as follows if you are draging a Text file in to the
' folder as a "Free Doc". If its a plain e-mail message, then the syntax is as follows:
' "/<Msg Subject>.EML"

Rec.DeleteRecord("test3.EML")
Rec.Close

set rec = nothing

Response.Write "Message deleted..." & "</BR>"
%>

<P> </P>

</BODY>
</HTML>
<!--

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Deleting Objects Using ADO

Visual Basic

Note The following example uses a file URL with the Exchange OLE DB (ExOLEDB) provider. The ExOLEDB provider also supports the HTTP URL scheme. Using the HTTP URL scheme allows both client and server applications to use a single URL scheme.
'Deleting Objects using ADO
'This sample shows how todelete object by given its local path
'Make reference to the ADO 2.5 library
'Make reference to Active DS Typy Library

Private Sub deleteitem()
Dim strDomainName As String
Dim strLocaPathOfObject As String
Dim strUser As String

strDomainName = GetDomainDNSName()
strUser = "user1"

' Sample 1: Delete a folder from 'MBX'
' specify the path of the folder to be deleted
strLocaPathOfObject = "MBX/" & strUser & "/Outbox/TestFolder"
Call TestDeleteObjects(strDomainName, strLocaPathOfObject)

' Sample 2: Delete a folder from 'Public Folders'
strLocaPathOfObject = "Public Folders/TestFolder"
Call TestDeleteObjects(strDomainName, strLocaPathOfObject)

' Sample 3: Delete a file from 'MBX'
strLocaPathOfObject = "MBX/" & strUser & "/Deleted Items/Hello.txt"
Call TestDeleteObjects(strDomainName, strLocaPathOfObject)

End Sub

Private Function GetDomainDNSName() As String
Dim Info As New ADSystemInfo
Dim strDomain As String
strDomain = Info.DomainDNSName

GetDomainDNSName = strDomain
End Function

Private Sub TestDeleteObjects(strDomainName As String, strLocalPathOfObject As String)
Dim Rec As New ADODB.Record
Dim strObjectUrl As String

' specify the url to the item to be deleted
strObjectUrl = "file://./backofficestorage/" & _
strDomainName & "/" & strLocalPathOfObject

MsgBox "strObjectUrl : " & strObjectUrl

' open Record
Rec.Open strObjectUrl, , adModeReadWrite

' delete object
Rec.DeleteRecord

' close the Record
Rec.Close

' clean up
Set Rec = Nothing

If Err.Number = 0 Then
Debug.Print "Good Job!"
End If
End Sub

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Moving Items

To move items within a public information store, use the Record.MoveRecord method. If you move a folder item, all items within the folder are also moved. You cannot use the Record.MoveRecord method to move items from one public information store or mailbox store to another.

VBScript

<job id="moveitems">
<reference object="adodb.record"/>
<script language="vbscript">

Function MoveItem( UrlFrom, UrlTo )

 Dim Rec
 Dim Conn
 Dim NewURL

 Set Conn = CreateObject("ADODB.Connection")
 Conn.Provider = "ExOLEDB.DataSource"
 Conn.Open UrlFrom

 Set Rec = CreateObject("ADODB.Record")
 Rec.Open URLFrom, Conn, adModeReadWrite
 NewURL = Rec.MoveRecord( , URLTo, , , adMoveOverWrite)
 MoveItem = NewURL

End Function
</script>
</job>

C++

#import <msado15.dll> no_namespace
#import <cdoex.dll> no_namespace

void moveitem(bstr_t urlfrom, bstr_t urlto) {

   _RecordPtr Rec(__uuidof(Record));
   _ConnectionPtr Conn(__uuidof(Connection));
   Conn->Provider = "ExOLEDB.DataSource";
   cout << urlfrom << endl;
   try {
      Conn->Open(urlfrom, bstr_t(""), bstr_t(""),-1);
   }
   catch(_com_error e) {
      // handle error or throw...
      throw e;
   }

   try {
      Rec->Open(
               variant_t(urlfrom),
               variant_t((IDispatch*)Conn, true),
               adModeReadWrite,
               adFailIfNotExists,
               adOpenSource,
               bstr_t(""),
               bstr_t(""));
   }
   catch(_com_error e) {
      // handle error or throw...
      throw e;
   }

   try {
      Rec->MoveRecord(
            bstr_t(),
            urlto,
            bstr_t(),
            bstr_t(),
            (MoveRecordOptionsEnum)adMoveOverWrite,
            VARIANT_FALSE);
   }
   catch(_com_error e) {
      // handle error or throw...
      throw e;
   }
}

Related Topics

  • Moving Items (WebDAV)

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Moving Items (WebDAV)

To move items using the WebDAV protocol, perform the following steps:

  1. Create a MOVE WebDAV request. The request Uniform Resource Identifier (URI) for the command is the URI to the item that you want to move.
  2. Set the Destination: HTTP header to the URI for the moved item.
  3. Send the request. The body of the request should be empty.
  4. If successful, the response status will be "201 Created".

The following example shows a typical MOVE request:

MOVE /pub2/folder1/folder2 HTTP/1.1
Destination: /pub2/folder1/folder3
Host: hostname

The following example uses an instance of the Microsoft.XMLHTTP Component Object Model (COM) class to send a MOVE protocol command to a Web Storage System server.

JScript

function copyItem( urisource, urito ) {

 var Req = new ActiveXObject("Microsoft.XMLHTTP");
 Req.open("MOVE", urisource, false);
 Req.setRequestHeader("Destination",urito);
 Req.send();
 return Req;

}

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Moving/Copying Using ADO

Visual Basic

Note The following example uses a file URL with the Exchange OLE DB (ExOLEDB) provider. The ExOLEDB provider also supports the HTTP URL scheme. Using the HTTP URL scheme allows both client and server applications to use a single URL scheme.
'CDO: Moving/Copying using CDOEx
'This sample shows how to Move/Copy objects

' This sample shows how to Move/Copy objects
'
' Make reference to  Exchange 2000 and ADO 2.5 libraries
' Make reference to Active DS Type Library

Private Sub Command1_Click()
    Dim strPathOfSourceObject As String
    Dim strPathOfDestFolder As String
    Dim strDomainName As String
    Dim strUser As String

    ' specify the domain and user
    strDomainName = GetDomainDNSName()
    strUser = "user1"

    ' Sample 1: Copy folders in 'MBX'
    strPathOfSourceObject = "MBX/" & strUser & "/Outbox/HelloFolder"
    strPathOfDestFolder = "MBX/" & strUser & "/Deleted Items"
    Call CopyMoveObjects(strDomainName, strPathOfSourceObject, strPathOfDestFolder, 0)

    ' Sample 2: Move folders in 'Public Folders'
    strPathOfSourceObject = "Public Folders/SourceFolder"
    strPathOfDestFolder = "Public Folders/DestFolder"
    'Call CopyMoveObjects(strDomainName, strPathOfSourceObject, strPathOfDestFolder, 1)

    ' Sample 3: move a file in 'MBX'
    strPathOfSourceObject = "MBX/" & strUser & "/Outbox/TestFolder/Hello.txt"
    strPathOfDestFolder = "MBX/" & strUser & "/Deleted Items"
    'Call CopyMoveObjects(strDomainName, strPathOfSourceObject, strPathOfDestFolder, 0)

    Unload Me
End Sub

' bOptinon:
' False: copy
' True - Move
'
Private Sub CopyMoveObjects(strDomainName As String, _
                                strLocalPathOfSourceObject As String, _
                                strLocalPathOfDestFolder As String, _
                                bOption As Boolean)
    Dim Rec As New ADODB.Record
    Dim strSourceObjectUrl As String
    Dim strDestFolderURL As String
    Dim strNewFolderName As String

    ' set the strURL to the location of the folders
    strSourceObjectUrl = "file://./backofficestorage/" & _
                 strDomainName & "/" & strLocalPathOfSourceObject

    ' open the record
    'Rec.Open strSourceObjectUrl  'OK with Copy
    Rec.Open strSourceObjectUrl, , adModeReadWrite  'Move needs parameter adModeReadWrite
    strNewFolderName = Rec.Fields("DAV:displayname")

    strDestFolderURL = "file://./backofficestorage/" & _
                 strDomainName & "/" & strLocalPathOfDestFolder

    If bOption = False Then
       'copy the folder from the source location to the destination folder
       Rec.CopyRecord strSourceObjectUrl, strDestFolderURL & "/" & strNewFolderName, , , adCopyOverWrite
    Else 'bOption = True
       Rec.MoveRecord strSourceObjectUrl, strDestFolderURL & "/" & strNewFolderName, , , adMoveOverWrite
    End If

    ' close the record
    Rec.Close

    ' clear up
    Set Rec = Nothing

    If Err.Number = 0 Then
      Debug.Print "Good Job!"
    End If

End Sub

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Accessing Item Streams

You can get an item's stream by using a Record or Recordset object's Fields collection. To request the stream, pass the index value of -1 adDefaultStream to the Fields.Item method.

When using CDO, you must use the CDO object's GetStream Method. You cannot retrieve the stream using the Fields collection.

Items that are collections, such as folders, do not have streams. Requesting the stream for these types of items causes an exception to be raised.

In the following example, the function receives a URL to an inbox item, gets the item's stream, and saves it to a file on disk.

VBScript

<job id="getstream">
<reference object="adodb.record"/>
<script language="vbscript">

Dim Stm
Dim Conn
Dim InfoNT
Dim sUrl
Dim sRelPath
Set InfoNT = CreateObject("WinNTSystemInfo")

sRelPath = "/public/test_folder/item4.txt"
sUrl = "http://" & InfoNT.Computername & sRelPath
Set Conn = CreateObject("ADODB.Connection")
Conn.Provider = "ExOLEDB.DataSource"
Conn.Open sUrl

Set Stm = getStream(sUrl, Conn)

If Stm.Type = adTypeText Then
  Wscript.echo Stm.ReadText
End If

' ...

'''''''''''''''''''''''''''''''''''''''
' getStream
'   sUrl - URL to item
'   Conn - Active Connection or Nothing
'
'''''''''''''''''''''''''''''''''''''''
Function getStream( sUrl, Conn)

 Dim Rec
 Dim Flds
 Dim sContentType

 Set Rec    = CreateObject("ADODB.Record")

 ' Did caller pass a Connection object reference?
 If Not ( VarType(Conn) = vbObject AND TypeName(Conn) = "Connection" ) Then
   Set Conn = CreateObject("ADODB.Connection")
   Conn.Provider = "ExOLEDB.DataSource"
   Conn.Open sUrl
 End If

 ' Try to open the item

 Rec.Open sUrl, Conn, adModeReadWrite
 Set Flds = Rec.Fields
 If Flds("DAV:isfolder") = True Or Flds("DAV:iscollection") = True Then
   Err.Raise &H80070057, "GetStream", "Item at URL is a collection."   ' E_INVALIDARG
 End If

 sContentType = flds("urn:schemas:mailheader:content-type")
 set stm = Flds(adDefaultStream).Value
 If Not sContentType = "" And InStr(sContentType, "text") > -1 Then
   Stm.Type = adTypeText
   If InStr(sContentType,"charset=") > -1 Then
    Stm.Charset = Mid(sContentType, InStr(sContentType, "charset=") + 8)
   End If
 End If

 Set getStream = Stm

End Function
</script>
</job>

The following examples demonstrates how to use native OLE DB interfaces in Microsoft® Visual C++® to write an item's stream and print an item's stream.

#include <oledb.h>
#include <msdasc.h>
#include <comdef.h>

#pragma comment(lib,"oledb.lib")
#pragma comment(lib,"msdasc.lib")

HRESULT writeItemStream( IRow* pRow, BYTE* pBytes, DWORD dwSize, ITransactionLocal* pTrans )
{

   if(pRow == NULL || pBytes == NULL)
      return E_INVALIDARG;

   HRESULT            hr               =   S_OK;
   DWORD            dwBindStatus      =   0;
   DWORD            dwLevel            =   0;

   IStream*         pStm            =   NULL;
   ULONG            cColumns         =   1;
   DBCOLUMNACCESS      rgColumns[1];

   VARIANT            vStm;

   if(pTrans != NULL) {
      hr = pTrans->StartTransaction(ISOLATIONLEVEL_UNSPECIFIED,0,NULL,&dwLevel);
      if(FAILED(hr))
         return hr;
   }

   VariantInit(&vStm);
   rgColumns[0].pData      = &vStm;
   rgColumns[0].columnid   = DBROWCOL_DEFAULTSTREAM;
   rgColumns[0].wType      = DBTYPE_VARIANT;
   rgColumns[0].cbDataLen   = sizeof(VARIANT);
   hr = pRow->GetColumns(cColumns, rgColumns);
   if(FAILED(hr))
      return hr;

   hr = vStm.punkVal->QueryInterface(&pStm);
   if(FAILED(hr)) {
      VariantClear(&vStm);
      return hr;
   }

   ULONG   cbWritten   =   0;
   if( FAILED( hr = pStm->Write((void*)pBytes, dwSize, &cbWritten) ) ) {
      VariantClear(&vStm);
      return hr;
   }

   ULARGE_INTEGER uLargeInt;
   uLargeInt.LowPart = dwSize;
   uLargeInt.HighPart = 0;
   if( FAILED(hr = pStm->SetSize(uLargeInt) ) ) {
      VariantClear(&vStm);
      return hr;
   }

   if(FAILED(hr = pStm->Commit(1)) ) {
      VariantClear(&vStm);
      return hr;
   }

   if(pTrans != NULL)
      hr = pTrans->Commit(FALSE, 0 , 0);

   VariantClear(&vStm);

   return hr;
}

#include <oledb.h>
#include <msdasc.h>
#pragma comment(lib,"oledb.lib")
#pragma comment(lib,"msdasc.lib")

#include <stdio.h>

#define BUF_SIZE   4096

HRESULT printStream(BSTR itemURL) {

   HRESULT         hr            =   S_OK;
   DWORD         dwBindStatus   =   0;
   IBindResource*   pBRes         =   NULL;
   IStream*      pStrm         =   NULL;
   char*         buf            =   new char[BUF_SIZE];
   ULONG         cbToRead      =   BUF_SIZE;
   ULONG         cbRead         =   0;
   CLSID         clsid_ExOLEDBProviderBinder;

   if(FAILED(hr = CLSIDFromProgID(L"ExOLEDB.Binder", &clsid_ExOLEDBProviderBinder)))
      return hr;

   if(itemURL == NULL)
      return E_INVALIDARG;

   hr = CoCreateInstance(
      clsid_ExOLEDBProviderBinder,
      NULL,
      CLSCTX_INPROC_SERVER,
      IID_IBindResource,
      (void**)&pBRes);

   if(FAILED(hr))
      goto Exit;

   hr = pBRes->Bind(
      NULL,
      itemURL,
      DBBINDURLFLAG_READ,
      DBGUID_STREAM,
      IID_IStream,
      NULL,
      NULL,
      &dwBindStatus,
      (IUnknown**) &pStrm);

   if(FAILED(hr))
      goto Exit;

   while(1) {
      hr=pStrm->Read((void*)buf,cbToRead,&cbRead);
      if(FAILED(hr)) {
         goto Exit;
      }

      if(hr==S_FALSE || cbRead == 0)
         break;

      for(unsigned int i = 0;i<cbRead;i++)
         printf("%c",buf[i]);
   }

Exit:

   delete [] buf;

   if(pBRes)
      pBRes->Release();
   if(pStrm)
      pStrm->Release();

   return hr;
}

Related Topics

  • Getting an Item's Stream (WebDAV)

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Getting an Item's Stream (WebDAV)

To create non-folder items using the WebDAV protocol, perform the following steps:

  1. Create a GET WebDAV request. The request Uniform Resource Identifier (URI) for the command is the URI to the item.
  2. Set the Translate: HTTP header to the value "f" (false).
  3. Send the request.
  4. If successful, the response status will be "200 OK."

The following example shows a typical GET request:

GET /pub2/folder1/folder2/item1.txt HTTP/1.1
Host: hostname
Translate: f

The following example uses an instance of the Microsoft.XMLHTTP Component Object Model (COM) class to send a GET protocol command to a Web Storage System server.

JScript

/*
** The getStream function returns a reference to an
** XMLHTTP object that should contain the stream for the
** specified item.
*/
function getStream( uri ){
 var Req = new ActiveXObject("Microsoft.XMLHTTP");
 Req.open("GET", uri, false);
 Req.setRequestHeader("Translate","f");
 Req.send();
 return Req;
}

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Using Transactions

When you use the server-side Exchange OLE DB (ExOLEDB) Provider, you can perform operations on items in a store as a single transaction. To do so, you first create a Microsoft® ActiveX® Data Objects (ADO) Connection object and bind to a particular store. Next, you invoke the _Connection.BeginTrans method. All operations that you subsequently perform within the context of this connection are not committed to the store until the transaction has been committed. To commit the transaction, you invoke the _Connection.CommitTrans method. To cancel the transaction, you invoke the _Connection.RollbackTrans method.

You cannot perform transactions across multiple stores. For example, you cannot create items in two public information stores as part of the same transaction.

The following example demonstrates how to perform the following operations, all within the context of a transaction:

  1. Create an application folder and set properties on the folder.
  2. Create a schema subfolder to house schema information for the application.
  3. Create three schema items: one content class definition and two property definitions.
  4. Create a test item in the application folder.

If the transaction is successful, the example then tests the schema information by using the test item created in the application folder. Because none of the operations are actually committed to the store before the transaction has been committed, the schema test operations cannot be performed in the transaction.

VBScript

<Job id="createFoldersAndSchemaFolders_Trans">

<reference object="adodb.record"/>

<script language="vbscript">

 option explicit
 Const s    = "urn:schemas-microsoft-com:exch-data:"
 Const dt        = "urn:schemas-microsoft-com:datatypes#"
 Const x   = "urn:schemas-microsoft-com:xml-data#"
 Const cc        = "urn:content-classes:"
 Const d       = "DAV:"
 Const pcc      = "urn:schemas-myorg-tld:content-classes:"
 Const p        = "urn:schemas-myorg-tld:"

 Const vRoot    = "/apps"
 Const appfldr  = "/apps/a2"
 Const pcc_1    = "class1"
 Const pcc_1_fn = "class1_pcc"
 Const pp_1     = "prop1"
 Const pp_1_fn  = "prop1_pp"
 Const pp_2     = "prop2"
 Const pp_2_fn  = "prop2_pp"

 Const test_fn  = "item.txt"

 createFoldersAndSchema_Trans vRoot, appfldr
 createTestItem appfldr & "/" & test_fn
 testSchema1 appfldr & "/" & test_fn
 testSchema2 appfldr

' -- createFolderAndSchema_Trans --
'
' This routine creates the following within a local transaction:
' - an application folder,
' - a schema folder "Schema" (child of app folder)
' - one custom content class definition
' - two custom property definitions (referenced by content class)
' - one test item in app folder with the custom content class
'
'
Sub createFoldersAndSchema_Trans( vRootURL, appfolderURL )

 WScript.Echo ""
 WScript.Echo "-- createFoldersAndSchema_Trans --"

 Dim Rec
 Dim Conn
 Dim info
 Dim infoNT
 Dim URL

 ' Get the fully qualified domain name from the ADSystemInfo object.
 Set info = CreateObject("ADSystemInfo")
 Set InfoNT = CreateObject("WinNTSystemInfo")
 Set Conn = CreateObject("ADODB.Connection")

 URL = "http://" & lcase(infoNT.computername) & _
                   "." & info.domaindnsname & _
                   appfolderURL

 wscript.echo url
 Conn.Provider = "ExOLEDB.DataSource"
 Conn.Open URL

 ' We now have a connection to the appropriate store
 ' Begin transaction
 Dim lvl
 lvl = Conn.BeginTrans

 Set Rec = CreateObject("ADODB.Record")

 ' Try to create the app folder. Use Connection with transaction
 With Rec
   .Open appfolderURL, Conn , adModeReadWrite, adCreateCollection Or adCreateOverwrite
   With .Fields
     .Item(d & "contentclass")             = cc & "folder"
     .Item(s & "schema-collection-ref")       = appfolderURL & "/Schema"
     .Item(s & "expected-content-class").Value    = Array(pcc & pcc_1)         'urn:schemas-myorg-tld:content-classes:class1
     .Update
   End With
   .Close

 ' Now create the folder for the schema items. By convention, this is the "Schema" folder below the App folder
   .Open appfolderURL & "/Schema", Conn, adModeReadWrite, adCreateCollection Or adCreateOverwrite
   With .Fields
     .Item(d & "contentclass").Value            = cc & "folder"
     .Item(s & "expected-content-class").Value  = _
       Array("urn:content-classes:propertydef", "urn:content-classes:contentclassdef","urn:content-classes:item")
     .Item(s & "baseschema").Value              = _
      Array(vRootURL & "/non_ipm_subtree/Schema")
     .Update
   End With
   .Close

   wscript.echo vRootURL & "/non_ipm_subtree/Schema"

  ' Create the first property definition. This property definition has the name
  '  urn:schemas-myorg-tld:prop1
   .Open appfolderURL & "/Schema/" & pp_1_fn, Conn, adModeReadWrite, adCreateNonCollection Or adCreateOverwrite
   With .Fields
     .Item(x  & "name")                 = p & pp_1
     .Item(d  & "contentclass")         = cc & "propertydef"
     .Item(dt & "type")                 = "date"
     .Item(s  & "isindexed")            = False
     .Item(s  & "ismultivalued")        = False
     .Item(s  & "isreadonly")           = False
     .Item(s  & "synchronize")          = False
     .Item(s  & "isrequired")           = False
     .Item(s  & "isvisible")            = True
     .Update
   End With
   .Close

  ' Create the second property definition. This property definition has the name
  '  urn:schemas-myorg-tld:prop2
   .Open appfolderURL & "/Schema/" & pp_2_fn, Conn, adModeReadWrite, adCreateNonCollection Or adCreateOverwrite
   With .Fields
     .Item(x  & "name")                 = p & pp_2
     .Item(d  & "contentclass")         = cc & "propertydef"
     .Item(dt & "type")                 = "string"
     .Item(s  & "isindexed")            = False
     .Item(s  & "ismultivalued")        = False
     .Item(s  & "isreadonly")           = False
     .Item(s  & "synchronize")          = False
     .Item(s  & "isrequired")           = False
     .Item(s  & "isvisible")            = True
     .Update
   End With
   .Close

  ' Create the content class definition. This class has the name
  '  urn:schemas-myorg-tld:content-classes:class1
   .Open appfolderURL & "/Schema/" & pcc_1_fn, Conn, adModeReadWrite, adCreateNonCollection Or adCreateOverwrite
   With .Fields
     .Item(d & "contentclass")                  = cc & "contentclassdef"
     .Item(x & "name")                          = pcc & pcc_1
     .Item(x & "extends").Value                 = Array(cc & "object")
     .Item(x & "element").Value                 = Array(p & pp_1, p & pp_2)
     .Item(s & "closedexpectedcontentclasses")  = False
     .Update
   End With
   .Close

 End with

 If Err.Number <> 0 Then
  wscript.echo "Error!"
  wscript.echo err.number
  wscript.echo err.description
  wscript.echo "Transaction Aborted"
  Conn.RollbackTrans
 Else
  Conn.CommitTrans
  wscript.echo "No Error. Transaction Completed"
 End if

  ' Create a test item. Set it's content class to our private class.
  ' When we open this item, the properties we defined for our content class
  ' should appear in Fields collection even though they have not been set.
   Rec.Open appfolderURL & "/" & test_fn, Conn, adModeReadWrite, adCreateNonCollection Or adCreateOverwrite
   With Rec.Fields
     .Item(d & "contentclass") = pcc & pcc_1
     .Item(adDefaultStream).Value.WriteText "Here is the text for the item."
     .Update
   End With
   Rec.Close

End Sub

Sub CreateTestItem( itemRelURL )
 Dim Rec
 Dim Conn
 Dim info
 Dim infoNT
 Dim URL

 ' Get the fully qualified domain name from the ADSystemInfo object.
 Set info   = CreateObject("ADSystemInfo")
 Set InfoNT = CreateObject("WinNTSystemInfo")
 Set Conn   = CreateObject("ADODB.Connection")
 Set Rec    = CreateObject("ADODB.Record")

 URL = "http://" & lcase(infoNT.computername) & _
                   "." & info.domaindnsname & _
                   itemRelURL

 wscript.echo url
 Conn.Provider = "ExOLEDB.DataSource"
 Conn.Open URL

  ' Create a test item. Set it's content class to our private class.
  ' When we open this item, the properties we defined for our content class
  ' should appear in Fields collection even though they have not been set.
   Rec.Open URL, Conn, adModeReadWrite, adCreateNonCollection Or adCreateOverwrite
   With Rec.Fields
     .Item(d & "contentclass") = pcc & pcc_1
     .Item(adDefaultStream).Value.WriteText "Here is the text for the item."
     .Update
   End With
   Rec.Close

End Sub

' -- testSchema1 --
' This routine checks the schema information set using the above routine.
' If the schema scope has been set up properly, the properties
' defined by our custom content class urn:schemas-myord-tld:content-classes:class1
' should appear in the Fields collection for the item even though values have not
' been set for these. If values have been set for these properties, this test
' tells us nothing.
'

Sub testSchema1( Path )

 WScript.Echo ""
 WScript.Echo "-- testSchema1 --"

 Dim Rec
 Set Rec = CreateObject("ADODB.Record")
 Dim Conn
 Set Conn = CreateObject("ADODB.Connection")

 Dim Info
 Set Info = CreateObject("ADSystemInfo")
 Dim InfoNT
 Set InfoNT = CreateObject("WinNTSystemInfo")

 Dim URL
 URL = "http://" & _
   lcase(InfoNT.ComputerName) & "." & _
        Info.DomainDNSName & _
        Path

 Conn.Provider = "ExOLEDB.DataSource"
 Conn.Open URL
 WScript.Echo "Testing schema using item at URL: " & URL
 Rec.Open URL, Conn

 Dim Fld
 For Each Fld in Rec.Fields
   If Fld.Name = (p & pp_1) Then
      WScript.Echo p & pp_1 & " returned in schema!"
   ElseIf Fld.Name = (p & pp_2) Then
      WScript.Echo p & pp_2 & " returned in schema!"
   End If
 Next

 Rec.Close
End Sub

' -- testSchema2 --
' This routine checks the schema information set using the above routine.
' If the schema scope has been set up properly, the properties
' defined by our custom content class urn:schemas-myord-tld:content-classes:class1
' should appear in the results of a "select *" in the appfolder.
'
Sub testSchema2( path )

 WScript.Echo ""
 WScript.Echo "-- testSchema2 --"

 Dim Conn
 Set Conn = CreateObject("ADODB.Connection")
 Dim Info
 Set Info = CreateObject("ADSystemInfo")
 Dim InfoNT
 Set InfoNT = CreateObject("WinNTSystemInfo")

 Dim URL
 URL = "http://" & _
   infont.computername & "." & _
        info.domaindnsname & "/" & _
        path

 Conn.Provider = "ExOLEDB.DataSource"
 Conn.Open URL

 Dim Rs
 Set Rs = CreateObject("ADODB.Recordset")
 Set Rs.ActiveConnection = Conn
 Rs.Open "select * from """ & path & """"

 Dim Fld
 For Each Fld In Rs.Fields
  If Fld.Name = (p & pp_1) Then
    WScript.Echo p & pp_1 & " returned in schema!"
  ElseIf Fld.Name = (p & pp_2) Then
    WScript.Echo p & pp_2 & " returned in schema!"
  End IF
 Next

End Sub

</script>
</job>

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Visual C++ Samples

The following Microsoft® Visual C++® samples are from .cpp source files. See the code comments in each sample for specific instructions about how to run the sample.

Traversing Folders (Private and Public) with OLEDB

Emptying the Deleted Items Folder with OLEDB

Creating Outlook Folders using CDOEX

Deleting Objects using CDOEX and ADO

Deleting Searched Objects using CDOEX and ADO

Moving/Copying Objects using CDOEX

Searching/Displaying Objects using CDOEX

Modifying Objects using CDOEX

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Traversing Folders (Private and Public) with OLEDB

Visual C++

Note The following example uses a file URL with the Exchange OLE DB (ExOLEDB) provider. The ExOLEDB provider also supports the HTTP URL scheme. Using the HTTP URL scheme allows both client and server applications to use a single URL scheme.
//Traversing Folders (Private and Public) with OLEDB
//
#include <stdio.h>
#include <conio.h>
#include <activeds.h>

#import <msado15.dll> no_namespace rename("EOF","adoEOF")
#import <cdoex.dll> no_namespace

HRESULT GetDomainName(BSTR * bstrDomainName);

struct StartOle
{
   StartOle() { CoInitialize(NULL); }
   ~StartOle() { CoUninitialize(); }
} _inst_StartOle;

void main(void)
{
   _ConnectionPtr conn(__uuidof(Connection));
   _RecordsetPtr MyFolders(__uuidof(Recordset));
   _RecordsetPtr MyPublicFolders(__uuidof(Recordset));
   _RecordPtr MyRecord(__uuidof(Record));
    _bstr_t strDomainName;
   BSTR bstrDomainDNSName;

   HRESULT hr = S_OK;
   HRESULT hRes = NULL;

   // Get your Domain Name.
   hr = GetDomainName(&bstrDomainDNSName);
    strDomainName = (_bstr_t)bstrDomainDNSName;

   try
   {
      //Open Private Folders under MBX
      conn->Provider = "Exoledb.DataSource";

      _bstr_t szConnString = "file://./backofficestorage/" + strDomainName + "/mbx/user1";

      hRes = conn->Open(szConnString,"","",0);

      _bstr_t strQ = "select * from scope ('shallow traversal of  \"" + szConnString + "\"') ";

      hRes = MyFolders->Open(strQ,conn->ConnectionString,adOpenForwardOnly,adLockReadOnly,0);

      printf("MailBox\n");

      int reccount = MyFolders->RecordCount;

      MyFolders->MoveFirst();

      FieldsPtr Flds ;
      FieldPtr Fld;
      _bstr_t strName;

      for (int i=0;i<reccount;i++)
      {
         Flds = MyFolders->GetFields();
         Fld = Flds->GetItem("DAV:displayname");
         strName = "----" + (_bstr_t)Fld->Value;
         printf("%s\n", (char *) strName );
         MyFolders->MoveNext();
      }

      conn->Close();
      MyFolders->Close();

      //Open Public Folders
      _bstr_t szPFConnString = "file://./backofficestorage/" + strDomainName + "/Public Folders";

      hRes = conn->Open(szPFConnString,"","",0);

      strQ = "select * from scope ('shallow traversal of  \"" + szPFConnString + "\"') ";

      hRes = MyPublicFolders->Open(strQ,conn->ConnectionString,adOpenForwardOnly,adLockReadOnly,0);

      printf("Public Folders\n");

      reccount = MyPublicFolders->RecordCount;
      MyPublicFolders->MoveFirst();

      for ( i=0;i<reccount;i++)
      {
         Flds = MyPublicFolders->GetFields();
         Fld = Flds->GetItem("DAV:displayname");
         strName = "----" + (_bstr_t)Fld->Value;
         printf("%s\n", (char *) strName);
         MyPublicFolders->MoveNext();
      }

      conn->Close();
      MyPublicFolders->Close();

   }
   catch(...)
   {
      printf("Something failed!\n");

   }
   conn = NULL;
}

/*******************************************
// GetDomainName
//
// Params: [out] BSTR * bstrDomainName
// Output: HRESULT
// Purpose: Retrieve the Domain DNS name.
********************************************/
HRESULT GetDomainName(BSTR * bstrDomainName)
{
   HRESULT hr = S_OK;
   IADsADSystemInfo *pADsys;

   hr = CoCreateInstance(   CLSID_ADSystemInfo,
                     NULL,
                     CLSCTX_INPROC_SERVER,
                     IID_IADsADSystemInfo,
                     (void**)&pADsys);

   hr = pADsys->get_DomainDNSName(bstrDomainName);

   if (pADsys)
      pADsys->Release();

   return hr;
}

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Emptying the Deleted Items Folder with OLEDB

Visual C++

Note The following example uses a file URL with the Exchange OLE DB (ExOLEDB) provider. The ExOLEDB provider also supports the HTTP URL scheme. Using the HTTP URL scheme allows both client and server applications to use a single URL scheme.
//Empty Deleted Items Folder with OLEDB
//This sample demonstrates how to delete mail items in Deleted Items Folder
//Using OLEDB.

#define DBINITCONSTANTS
#define NUMROWS_CHUNK  5
#define INITGUID
#include <windows.h>
#include <stdio.h>
#include <oledb.h>
#include <oledberr.h>

int main(int argc, char** argv)
{
   HRESULT hr = S_OK;

   if (argc !=2)
   {
      printf("Usage: EmptyDeletedItems\r\n");
      printf("Example: EmptyDeletedItems \"file://./backofficestorage/MangoDomain.extest.microsoft.com/MBX/User1Mango3/Deleted Items\"\n");
      exit(0);
   }

   wchar_t* folderURL = NULL;
   size_t size;
   size = mbstowcs(NULL,argv[1],0);
   folderURL = (wchar_t*)malloc(size * sizeof(wchar_t*) + 1);
   mbstowcs(folderURL,argv[1],size+1);
   printf("folderURL: %ls\n", folderURL);
   BSTR bstrFolderURL = SysAllocString(folderURL);
   printf("Folder URL: %S\n", bstrFolderURL);

   wchar_t* strURL = NULL;
   wchar_t* str1 = L"Select * from scope('shallow traversal of \"";
   wchar_t* str2 = L"\"')";
   size_t size2, size3;
   size2 = mbstowcs(NULL, "Select * from scope('shallow traversal of \"", 0);
   size3 = mbstowcs(NULL, "\')", 0);
   strURL = (wchar_t*)malloc(size * sizeof(wchar_t*) + size2 + size3 + 1);
   wcscpy(strURL, str1);
   wcscat(strURL, folderURL);
   wcscat(strURL, str2);
   printf("strURL: %ls\n", strURL);

   IDBInitialize *pIDBInitialize;

   //DB Prop variables
   const ULONG nProps = 4;
   IDBProperties *pIDBProperties;
   DBPROP        InitProp[nProps];
   DBPROPSET     rgInitPropSet;

   //Session vars
   IDBCreateSession *pIDBCreateSession;

   //command vars
   IDBCreateCommand *pIDBCreateCommand;
   ICommandText     *pICommandText;

   LONG      cRowsAffected;

   //rowset vars
   IRowset *pIRowset;
   IRowsetChange *pIRowsetChange;

   ULONG cRowsObtained ; //rows fetched
   HROW  rghRows[NUMROWS_CHUNK] ; //rows handle
   HROW *pRows = &rghRows[0];  //ptr to row

   DBROWSTATUS *rgRowStatus = NULL;

   CLSID CLSID_EXOLEDB;
   int MsgCount = 0;

   //Init OLE and set up the DLLs
   CoInitialize(NULL);

   // create an instance of exchange oledb provider
   //Request one of the instance such as IDBInitialize, or IDBProperties

   hr = CLSIDFromProgID(OLESTR("Exoledb.DataSource"), &CLSID_EXOLEDB);
   if (FAILED(hr))
   {
      printf("CLSIDFromProgID failed\n");
      return (E_FAIL);
   }

   hr = CoCreateInstance(CLSID_EXOLEDB,
                    NULL,
                    CLSCTX_INPROC_SERVER,
                    IID_IDBInitialize,
                    (void**)&pIDBInitialize);

   if(pIDBInitialize == NULL)
   {
      printf("CoCreateInstance of Provider failed\n");
      return (E_FAIL);
   }

   //Get or set prop data source
   //total four props
   //level of desired prompting
   //data source name
   //user id
   //password
   //Init common prop optins
   for (ULONG i=0; i<nProps; i++)
   {
      VariantInit(&InitProp[i].vValue);
      InitProp[i].dwOptions = DBPROPOPTIONS_REQUIRED;
      InitProp[i].colid = DB_NULLID;
   }

   //level of prompting that will be done to complete the conn
   InitProp[0].dwPropertyID = DBPROP_INIT_PROMPT;
   InitProp[0].vValue.vt = VT_I2;
   InitProp[0].vValue.intVal = DBPROMPT_NOPROMPT;

   //data source name
   InitProp[1].dwPropertyID = DBPROP_INIT_DATASOURCE;
   InitProp[1].vValue.vt = VT_BSTR;
   InitProp[1].vValue.bstrVal = bstrFolderURL;

   //user id
   InitProp[2].dwPropertyID = DBPROP_AUTH_USERID;
   InitProp[2].vValue.vt = VT_BSTR;
   InitProp[2].vValue.bstrVal = SysAllocString(OLESTR(""));

   //passwd
   InitProp[3].dwPropertyID = DBPROP_AUTH_PASSWORD;
   InitProp[3].vValue.vt = VT_BSTR;
   InitProp[3].vValue.bstrVal = SysAllocString(OLESTR(""));

   rgInitPropSet.guidPropertySet = DBPROPSET_DBINIT;
   rgInitPropSet.rgProperties = InitProp;
   rgInitPropSet.cProperties = nProps;

   //set the init props
   //query the IDBProperties interface first
   hr = pIDBInitialize->QueryInterface(IID_IDBProperties,
                              (void**)&pIDBProperties);
   if( FAILED(hr))
   {
      printf("Query IDBPropeties failed\n");
      return E_FAIL;
   }

   hr = pIDBProperties->SetProperties(1,
                              &rgInitPropSet);
   if( FAILED(hr))
   {
      printf("Set IDBPropeties failed\n");
      return E_FAIL;
   }

   //successful and release
   SysFreeString(InitProp[1].vValue.bstrVal);
   SysFreeString(InitProp[2].vValue.bstrVal);
   SysFreeString(InitProp[3].vValue.bstrVal);

   pIDBProperties->Release();

   //call IDBInitialize::Initilize() to get datasource
   hr = pIDBInitialize->Initialize();
   if(FAILED(hr))
   {
      printf("IDBInitialize failed\n");
      return E_FAIL;
   }

   //QI IDBCreateSession
   hr = pIDBInitialize->QueryInterface(IID_IDBCreateSession,
                              (void **)&pIDBCreateSession);

   if( FAILED(hr))
   {
      printf("Query IDBCreateSession failed\n");
      return E_FAIL;
   }

   //Create the session, Session object: IDBCreateCommand::CreateCommand
   hr = pIDBCreateSession->CreateSession(NULL,
                                IID_IDBCreateCommand,
                                (IUnknown**) &pIDBCreateCommand);
   //relesase the session
   pIDBCreateSession->Release();

   if( FAILED(hr))
   {
      printf("CreateSession failed\n");
      return E_FAIL;
   }

   //create the command object
   hr = pIDBCreateCommand->CreateCommand(NULL,
                                IID_ICommandText,
                                (IUnknown**)&pICommandText);

   pIDBCreateCommand->Release();

   if( FAILED(hr))
   {
      printf("CreateCommand failed");
      return E_FAIL;
   }

   //ICommandText::SetCommandText()
   hr = pICommandText->SetCommandText(DBGUID_DBSQL,
                              strURL);

   if( FAILED(hr))
   {
      printf("set ComamndText failed");
      return E_FAIL;
   }

   //ICommand::Excecute() to retrieve the rowset
   hr = pICommandText->Execute(NULL,
                              IID_IRowset,
                        NULL,
                        &cRowsAffected,
                        (IUnknown**)&pIRowset);

   pICommandText->Release();

   if(FAILED(hr))
   {
      printf("Exe ComamndText failed\n");
      return E_FAIL;
   }

   // Query IRowsetChange to delete rows
   hr = pIRowset->QueryInterface(IID_IRowsetChange,
                         (void**)&pIRowsetChange);
   if( FAILED(hr))
   {
      printf("Query IRowsetChange failed\n");
      return E_FAIL;
   }

   //Move throught the rowset using GetNextRow() to retrieve the handles
   //to the next row
   while(TRUE)
   {
      pIRowset ->GetNextRows(
         0, //reserved
         0, //cRowsToSkip
         NUMROWS_CHUNK,
         &cRowsObtained,
         &pRows //filled in w/row handle
         );

      //all done , no more rows left to get
      if(cRowsObtained == 0)
         break;

      MsgCount += cRowsObtained;

      rgRowStatus = new DBROWSTATUS[cRowsObtained];

      // delete messages
      pIRowsetChange->DeleteRows(DB_NULL_HCHAPTER,
                           cRowsObtained,
                           rghRows,
                           rgRowStatus);

      //release row handles
      pIRowset->ReleaseRows(cRowsObtained, rghRows, NULL, NULL, NULL);

      delete [] rgRowStatus;

   }//end of while
   printf("\nNumber of items(messages) deleted from Deleted Items Folder: %d\n", MsgCount);

   //release IRowsetChange
   pIRowsetChange->Release();

   SysFreeString(folderURL);
   CoUninitialize();
   return NOERROR;
}

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Creating Outlook Folders Using CDOEX

Visual C++

Note The following example uses a file URL with the Exchange OLE DB (ExOLEDB) provider. The ExOLEDB provider also supports the HTTP URL scheme. Using the HTTP URL scheme allows both client and server applications to use a single URL scheme.
//Create Outlook special folders using CDO
//Modify the code where you see TODO and make sure the objects or properties exist

#include <activeds.h>
#include <stdio.h>
#include <conio.h>
#import <msado15.dll> no_namespace rename("EOF","adoEOF")
#import <cdoex.dll> no_namespace

struct StartOle {
   StartOle() { CoInitialize(NULL); }
   ~StartOle() { CoUninitialize(); }
} _inst_StartOle;

void dump_com_error(_com_error &e)
{
    printf("Oops - hit an error!\n");
    printf("\tCode = %08lx\n", e.Error());
    printf("\tCode meaning = %s\n", e.ErrorMessage());
    _bstr_t bstrSource(e.Source());
    _bstr_t bstrDescription(e.Description());
    printf("\tSource = %s\n", (LPCTSTR) bstrSource);
    printf("\tDescription = %s\n", (LPCTSTR) bstrDescription);
}

void CreateFolder(_bstr_t strDomainName, _bstr_t strLocalPathOfParentFolder, _bstr_t strNewFolderName, _bstr_t strFolderType);
HRESULT GetDomainName(BSTR * bstrDomainName);

void main(void)
{
    _bstr_t strDomainName;
    _bstr_t strLocalPathOfParentFolder;
    _bstr_t strNewFolderName;
    _bstr_t strUser;

   HRESULT hr = S_OK;
   BSTR bstrDomainDNSName;
   // Get your Domain Name.
   hr = GetDomainName(&bstrDomainDNSName);

    strDomainName = (_bstr_t)bstrDomainDNSName;

    strUser = "user1";   // TODO
    strNewFolderName = "TestHelloFolder";  //TODO

    // Sample 1: Create a folder in 'MBX' to hold 'AppointmentItem'
    // specify the path of the folder under which a folder to be created
    strLocalPathOfParentFolder = "MBX/" + strUser + "/Deleted Items";

    CreateFolder(strDomainName, strLocalPathOfParentFolder, strNewFolderName, (_bstr_t)"IPF.Appointment");

    // Sample 2: Create a folder in 'Public Folders' to hold 'ContactItem'
    // specify the path of the folder under which a folder to be created
    strLocalPathOfParentFolder = "Public Folders";

    CreateFolder(strDomainName, strLocalPathOfParentFolder, strNewFolderName, (_bstr_t)"IPF.Contact");

}

/**
Create all kind of Outlook folders

strFolderType    Name

MailItems                IPF.Note
ContactItems           IPF.Contact
AppointmentItems    IPF.Appointment
NoteItems               IPF.StickyNote
TaskItems               IPF.Task
JournalItems            IPF.Journal
 */
void CreateFolder(_bstr_t strDomainName, _bstr_t strLocalPathOfParentFolder, _bstr_t strNewFolderName, _bstr_t strFolderType)
{
   _ConnectionPtr conn(__uuidof(Connection));
   _RecordPtr Rec(__uuidof(Record));
   _bstr_t strFolderUrl;

   HRESULT hr = S_OK;

            try
     {
             // specify the url to the folder to be created
             strFolderUrl = "file://./backofficestorage/" + strDomainName + "/" + strLocalPathOfParentFolder + "/" + strNewFolderName;

      //Open main Mailbox Folders under MBX
      conn->Provider = "Exoledb.DataSource";
      hr = conn->Open(strFolderUrl,"","",0);

      hr = Rec->Open((_variant_t)strFolderUrl,conn->ConnectionString,
            adModeReadWrite,
            adCreateCollection,
            adOpenSource,
            L"", L"");

      // set content-class
      FieldsPtr Flds = Rec->GetFields();
      FieldPtr Fld = Flds->GetItem("DAV:contentclass");
              Fld->Value = _variant_t("urn:content-classes:folder");

      // specify folder type
      Fld = Flds->GetItem("http://schemas.microsoft.com/exchange/outlookfolderclass");
              Fld->Value = (_variant_t)strFolderType;

      // update
      Flds->Update();

      // close connection
      Rec->Close();
      conn->Close();

      // clear up
      Flds = NULL;
      Fld = NULL;
      Rec = NULL;
      conn = NULL;

       printf("Good Job!");

     }
     catch(_com_error &e)
     {
         dump_com_error(e);
     }

}

/*****************************************************************************/
// GetDomainName
//
// Params: [out] BSTR * bstrDomainName
// Output: HRESULT
// Purpose: Retrieve the Domain DNS name.
/*****************************************************************************/
HRESULT GetDomainName(BSTR * bstrDomainName)
{
HRESULT hr = S_OK;
IADsADSystemInfo *pADsys;
hr = CoCreateInstance(CLSID_ADSystemInfo,
NULL,
CLSCTX_INPROC_SERVER,
IID_IADsADSystemInfo,
(void**)&pADsys);
hr = pADsys->get_DomainDNSName(bstrDomainName);

if (pADsys)
pADsys->Release();
return hr;
}

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Deleting Objects Using CDOEX and ADO

Visual C++

Note The following example uses a file URL with the Exchange OLE DB (ExOLEDB) provider. The ExOLEDB provider also supports the HTTP URL scheme. Using the HTTP URL scheme allows both client and server applications to use a single URL scheme.
//Delete Object using Record by giving the object's local path
//Modify the code where you see TODO and make sure the objects or roperties exist

#include <activeds.h>
#include <stdio.h>
#include <conio.h>
#import <msado15.dll> no_namespace rename("EOF","adoEOF")
#import <cdoex.dll> no_namespace

struct StartOle {
   StartOle() { CoInitialize(NULL); }
   ~StartOle() { CoUninitialize(); }
} _inst_StartOle;

void dump_com_error(_com_error &e)
{
    printf("Oops - hit an error!\n");
    printf("\tCode = %08lx\n", e.Error());
    printf("\tCode meaning = %s\n", e.ErrorMessage());
    _bstr_t bstrSource(e.Source());
    _bstr_t bstrDescription(e.Description());
    printf("\tSource = %s\n", (LPCTSTR) bstrSource);
    printf("\tDescription = %s\n", (LPCTSTR) bstrDescription);
}

void DeleteObjects(_bstr_t strDomainName, _bstr_t strLocalPathOfObject);
HRESULT GetDomainName(BSTR * bstrDomainName);

void main(void)
{
    _bstr_t strDomainName;
    _bstr_t strLocalPathOfObject;
    _bstr_t strUser;

    HRESULT hr = S_OK;
    BSTR bstrDomainDNSName;
    // Get your Domain Name.
    hr = GetDomainName(&bstrDomainDNSName);

     strDomainName = (_bstr_t)bstrDomainDNSName;

    strUser = "user1";  // TODO

    // Sample 1: Delete a folder from 'MBX'
    // specify the path of the folder to be deleted
    strLocalPathOfObject = "MBX/" + strUser + "/Deleted Items/TestFolder";  // TODO

    DeleteObjects(strDomainName, strLocalPathOfObject);

     // Sample 3: Delete a file 'Hello.txt' from public folder
    // specify the path of the folder to be deleted
    strLocalPathOfObject = "Public Folders/TestFolder/Hello.txt";   // TODO

    DeleteObjects(strDomainName, strLocalPathOfObject);
   // Sample 2: Delete a folder from 'Public Folders'
    // specify the path of the folder to be deleted
    strLocalPathOfObject = "Public Folders/TestFolder";   // TODO

    DeleteObjects(strDomainName, strLocalPathOfObject);

}

/************************************
Delete object using Record

************************************/
void DeleteObjects(_bstr_t strDomainName, _bstr_t strLocalPathOfObject)
{
   _ConnectionPtr conn(__uuidof(Connection));
   _RecordPtr Rec(__uuidof(Record));

   _bstr_t strObjectUrl;

   HRESULT hr = S_OK;

   try
      {

              // specify the url to the item to be deleted
              strObjectUrl = "file://./backofficestorage/" + strDomainName + "/" + strLocalPathOfObject;

      //Open connection
      conn->Provider = "Exoledb.DataSource";
      hr = conn->Open(strObjectUrl,"","",0);

      hr = Rec->Open((_variant_t)strObjectUrl,conn->ConnectionString,
            adModeReadWrite,
            adFailIfNotExists,
            adOpenSource,
            L"", L"");

      // delete object
              Rec->DeleteRecord(strObjectUrl, false);

      // close connection
      Rec->Close();
      conn->Close();

          // clean up
          Rec = NULL;
          conn = NULL;

      printf("Good Job\n");

     }
     catch(_com_error &e)
    {
          dump_com_error(e);
    }

}

/*************************************************************************
// GetDomainName
//
// Params: [out] BSTR * bstrDomainName
// Output: HRESULT
// Purpose: Retrieve the Domain DNS name.
**************************************************************************/
HRESULT GetDomainName(BSTR * bstrDomainName)
{
HRESULT hr = S_OK;
IADsADSystemInfo *pADsys;
hr = CoCreateInstance(CLSID_ADSystemInfo,
NULL,
CLSCTX_INPROC_SERVER,
IID_IADsADSystemInfo,
(void**)&pADsys);
hr = pADsys->get_DomainDNSName(bstrDomainName);

if (pADsys)
pADsys->Release();
return hr;
}

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Deleting Searched Objects Using CDOEX and ADO

Visual C++

Note The following example uses a file URL with the Exchange OLE DB (ExOLEDB) provider. The ExOLEDB provider also supports the HTTP URL scheme. Using the HTTP URL scheme allows both client and server applications to use a single URL scheme.
//Delete searched objects using Recordset and CDO
//Modify the code where you see TODO and make sure the objects or properties exist
#include <activeds.h>
#include <stdio.h>
#include <conio.h>
#import <msado15.dll> no_namespace rename("EOF","adoEOF")
#import <cdoex.dll> no_namespace

struct StartOle {
   StartOle() { CoInitialize(NULL); }
   ~StartOle() { CoUninitialize(); }
} _inst_StartOle;

void dump_com_error(_com_error &e)
{
    printf("Oops - hit an error!\n");
    printf("\tCode = %08lx\n", e.Error());
    printf("\tCode meaning = %s\n", e.ErrorMessage());
    _bstr_t bstrSource(e.Source());
    _bstr_t bstrDescription(e.Description());
    printf("\tSource = %s\n", (LPCTSTR) bstrSource);
    printf("\tDescription = %s\n", (LPCTSTR) bstrDescription);
}

void DeleteSeachedObjects(_bstr_t strDomainName, _bstr_t strLocalPathOfSourceFolder, _bstr_t strSearchSql);
HRESULT GetDomainName(BSTR * bstrDomainName);

void main(void)
{
    _bstr_t strDomainName;
    _bstr_t strLocalPathOfSourceFolder;
    _bstr_t strSourceFolderUrl;
    _bstr_t strSearchSql;
    _bstr_t strUser;

   HRESULT hr = S_OK;
   BSTR bstrDomainDNSName;
   // Get your Domain Name.
   hr = GetDomainName(&bstrDomainDNSName);

    strDomainName = (_bstr_t)bstrDomainDNSName;

    strUser = "user1";   // TODO

    // Sample 1: Delete the appointemnts with subject "Test Appointment"  in 'Calendar';
    strLocalPathOfSourceFolder = "MBX/" + strUser + "/Calendar";
    strSourceFolderUrl = "file://./backofficestorage/" + strDomainName + "/" + strLocalPathOfSourceFolder;

    // create the SQL query for the recordset (appointments)
    strSearchSql = "select ";
    strSearchSql = strSearchSql + "\"urn:schemas:mailheader:content-class\"";
    strSearchSql = strSearchSql + ", \"DAV:href\"";
    strSearchSql = strSearchSql + ", \"DAV:displayname\"";
    strSearchSql = strSearchSql + ", \"DAV:isfolder\"";
    strSearchSql = strSearchSql + ", \"DAV:iscollection\"";
    strSearchSql = strSearchSql + ", \"urn:schemas:httpmail:subject\"";
    strSearchSql = strSearchSql + " from scope ('shallow traversal of ";
    strSearchSql = strSearchSql + "\"" + strSourceFolderUrl + "\"" + "')";
    strSearchSql = strSearchSql + " WHERE \"DAV:ishidden\" = false";
    strSearchSql = strSearchSql + " AND \"DAV:isfolder\" = false";
    strSearchSql = strSearchSql + " AND \"urn:schemas:httpmail:subject\" = 'Test Appointment'";   // TODO

    DeleteSeachedObjects(strDomainName, strLocalPathOfSourceFolder, strSearchSql);

    // Sample 2: Delete a file Hello.txt from  "Deleted Items" folder
    strLocalPathOfSourceFolder = "MBX/" + strUser + "/Deleted Items";
    strSourceFolderUrl = "file://./backofficestorage/" + \
                 strDomainName + "/" + strLocalPathOfSourceFolder;

    // create the SQL query for the recordset (appointments)
    strSearchSql = "select ";
    strSearchSql = strSearchSql + "\"urn:schemas:mailheader:content-class\"";
    strSearchSql = strSearchSql + ", \"DAV:href\"";
    strSearchSql = strSearchSql + ", \"DAV:displayname\"";
    strSearchSql = strSearchSql + ", \"DAV:isfolder\"";
    strSearchSql = strSearchSql + ", \"urn:schemas:httpmail:subject\"";
    strSearchSql = strSearchSql + " from scope ('shallow traversal of ";
    strSearchSql = strSearchSql + "\"" + strSourceFolderUrl + "\"" + "')";
    strSearchSql = strSearchSql + " WHERE \"DAV:ishidden\" = false";
    strSearchSql = strSearchSql + " AND \"DAV:isfolder\" = false";
    strSearchSql = strSearchSql + " AND \"DAV:displayname\" = 'Hello.txt'";   // TODO

    DeleteSeachedObjects(strDomainName, strLocalPathOfSourceFolder, strSearchSql);

    // Sample 3: Delete tje subfolder "TestFolder" of 'Public Folders'
    strLocalPathOfSourceFolder = "Public Folders";
    strSourceFolderUrl = "file://./backofficestorage/" + strDomainName + "/" + strLocalPathOfSourceFolder;

    // create the SQL query for the recordset (appointments)
    strSearchSql = "select ";
    strSearchSql = strSearchSql + "\"urn:schemas:mailheader:content-class\"";
    strSearchSql = strSearchSql + ", \"DAV:href\"";
    strSearchSql = strSearchSql + ", \"DAV:displayname\"";
    strSearchSql = strSearchSql + ", \"DAV:isfolder\"";
    strSearchSql = strSearchSql + ", \"urn:schemas:httpmail:subject\"";
    strSearchSql = strSearchSql + " from scope ('shallow traversal of ";
    strSearchSql = strSearchSql + "\"" + strSourceFolderUrl + "\"" + "')";
    strSearchSql = strSearchSql + " WHERE \"DAV:ishidden\" = false";
    strSearchSql = strSearchSql + " AND \"DAV:isfolder\" = true";
    strSearchSql = strSearchSql + " AND \"DAV:displayname\" = 'TestFolder'";    // TODO

    DeleteSeachedObjects(strDomainName, strLocalPathOfSourceFolder, strSearchSql);

}

/*********************************
// Delete searched Objects using Recordset
//
*********************************/
void DeleteSeachedObjects(_bstr_t strDomainName, _bstr_t strLocalPathOfSourceFolder, _bstr_t strSearchSql)
{
   _ConnectionPtr conn(_uuidof(Connection));
   _RecordsetPtr Rst(_uuidof(Recordset));
       _bstr_t strSourceFolderUrl;

   HRESULT hr = S_OK;

   try
   {
              // set the URL to the location of the folders
              strSourceFolderUrl = "file://./backofficestorage/" + strDomainName + "/" + strLocalPathOfSourceFolder;

      // open connection
      conn->Provider = "Exoledb.DataSource";
      hr = conn->Open(strSourceFolderUrl,"","",0);

      if (conn->State == adStateOpen)
         printf("Connection Opened!\n");
      else
         printf("Connection failed!\n");

      // open Recordset
      hr = Rst->Open(strSearchSql,conn->ConnectionString,adOpenForwardOnly,adLockOptimistic,0);  //du test

      if (Rst->State == adStateOpen)
         printf("Rst Opened Successfully!\n");
      else
         printf("Rst Opened Failed!\n");

      // check if found any objects
      if (Rst->RecordCount == 0)
      {
                     printf("No object has been found!\n");
         return;
      }

      // now found some objects
      hr = Rst->MoveFirst();

      _bstr_t strResult = "";
      while (VARIANT_FALSE == Rst->adoEOF)
      {

                     Rst->Delete(adAffectCurrent);  //Delete the current one

         /*
         // you cam slo make further restriction to the objects to be deleted
         // here shows the idea how
                     _bstr_t strObjectName;

                     // retrieve some propertied to be used in Copy
         FieldsPtr Flds = Rst->GetFields();
         FieldPtr Fld = Flds->GetItem("DAV:displayname");
         strObjectName = (_bstr_t)(Fld->Value);

         printf("strObjectUrl : %s\n", (char *)strObjectName);

                     if (wcsicmp(strObjectName, (_bstr_t)"Hello.txt") == 0)   // TODO
            Rst->Delete(adAffectCurrent);  //Delete the current one
         */

         Rst->MoveNext();
      }

      // close connections
      Rst->Close();
      conn->Close();

      // clear up
          Rst = NULL;
          conn = NULL;

      printf("Good Job!\n");
   }
   catch(_com_error &e)
   {
       dump_com_error(e);
   }
}

/*************************************************
// GetDomainName
//
// Params: [out] BSTR * bstrDomainName
// Output: HRESULT
// Purpose: Retrieve the Domain DNS name.
**************************************************/
HRESULT GetDomainName(BSTR * bstrDomainName)
{
HRESULT hr = S_OK;
IADsADSystemInfo *pADsys;
hr = CoCreateInstance(CLSID_ADSystemInfo,
NULL,
CLSCTX_INPROC_SERVER,
IID_IADsADSystemInfo,
(void**)&pADsys);
hr = pADsys->get_DomainDNSName(bstrDomainName);

if (pADsys)
pADsys->Release();
return hr;
}

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Moving/Copying Objects Using CDOEX

Visual C++

Note The following example uses a file URL with the Exchange OLE DB (ExOLEDB) provider. The ExOLEDB provider also supports the HTTP URL scheme. Using the HTTP URL scheme allows both client and server applications to use a single URL scheme.
//Move/Copy objects using CDO
//Modify the code where you see TODO and make sure the objects or properties exist
#include <activeds.h>
#include <stdio.h>
#include <conio.h>
#import <msado15.dll> no_namespace rename("EOF","adoEOF")
#import <cdoex.dll> no_namespace

struct StartOle {
   StartOle() { CoInitialize(NULL); }
   ~StartOle() { CoUninitialize(); }
} _inst_StartOle;

void dump_com_error(_com_error &e)
{
    printf("Oops - hit an error!\n");
    printf("\tCode = %08lx\n", e.Error());
    printf("\tCode meaning = %s\n", e.ErrorMessage());
    _bstr_t bstrSource(e.Source());
    _bstr_t bstrDescription(e.Description());
    printf("\tSource = %s\n", (LPCTSTR) bstrSource);
    printf("\tDescription = %s\n", (LPCTSTR) bstrDescription);
}

void CopyMoveObjects(_bstr_t strDomainName, _bstr_t strLocalPathOfSourceObject, _bstr_t strLocalPathOfDestFolder, bool bOption);
HRESULT GetDomainName(BSTR * bstrDomainName);

void main(void)
{
    _bstr_t strDomainName;
    _bstr_t strLocalPathOfSourceObject;
    _bstr_t strLocalPathOfDestFolder;
    _bstr_t strUser;

   HRESULT hr = S_OK;
   BSTR bstrDomainDNSName;
   // Get your Domain Name.
   hr = GetDomainName(&bstrDomainDNSName);

    strDomainName = (_bstr_t)bstrDomainDNSName;

    strUser = "user1";  // TODO

      // Sample 3: Move files in 'MBX'
    strLocalPathOfSourceObject = "MBX/" + strUser + "/Outbox/TestFolder/Hello.txt";
    strLocalPathOfDestFolder = "MBX/" + strUser + "/Deleted Items";

    CopyMoveObjects(strDomainName, strLocalPathOfSourceObject, strLocalPathOfDestFolder, true);

    // Sample 1: Copy folders in 'MBX'
    strLocalPathOfSourceObject = "MBX/" + strUser + "/Outbox/TestFolder";
    strLocalPathOfDestFolder = "MBX/" + strUser + "/Deleted Items";

    CopyMoveObjects(strDomainName, strLocalPathOfSourceObject, strLocalPathOfDestFolder, false);

    // Sample 2: Move folders in 'Public Folders'
    strLocalPathOfSourceObject = "Public Folders/SourceFolder";
    strLocalPathOfDestFolder = "Public Folders/DestFolder";

    CopyMoveObjects(strDomainName, strLocalPathOfSourceObject, strLocalPathOfDestFolder, true);

}

/********************************************
// CopyMove Objects
// bOption:
/ /True : move
// False: copy
********************************************/

void CopyMoveObjects(_bstr_t strDomainName, _bstr_t strLocalPathOfSourceObject, _bstr_t strLocalPathOfDestFolder, bool bOption)
{
   _ConnectionPtr conn(__uuidof(Connection));
   _RecordPtr Rec(__uuidof(Record));

       _bstr_t strSourceObjectUrl;
       _bstr_t strDestFolderUrl;
       _bstr_t strObjectName;

   HRESULT hr = S_OK;

   try
   {

      // set the URL to the location of the source folder
              strSourceObjectUrl = "file://./backofficestorage/" + strDomainName + "/" + strLocalPathOfSourceObject;
              printf("strSourceObjectUrl = %s\n", (char *)strSourceObjectUrl);

      // open connection
      conn->Provider = "Exoledb.DataSource";
      hr = conn->Open(strSourceObjectUrl,"","",0);

      // open the record
      hr = Rec->Open((_variant_t)strSourceObjectUrl,
            conn->ConnectionString,
            adModeReadWrite,
            adFailIfNotExists,
            adOpenSource,
            L"", L"");

      strObjectName = (_bstr_t)Rec->Fields->GetItem((_variant_t)"DAV:displayname")->Value;

      // set the URL to the location of the destination folder
      strDestFolderUrl = "file://./backofficestorage/" + strDomainName + "/" + strLocalPathOfDestFolder;

      if (bOption)
         // move the folder from the source location to the destination folder
         Rec->MoveRecord(strSourceObjectUrl,
                       strDestFolderUrl  + "/" + strObjectName,
                       "", "",
                       adMoveOverWrite,
                       false);
      else
         // copy the folder from the source location to the destination folder
         Rec->CopyRecord(strSourceObjectUrl,
                       strDestFolderUrl  + "/" + strObjectName,
                       "", "",
                       adCopyOverWrite,
                       false);

      // close connections
      Rec->Close();
      conn->Close();

      // clear up
          Rec = NULL;
          conn = NULL;

      printf("Good Job!\n");

   }
   catch(_com_error &e)
   {
      dump_com_error(e);
   }
}

/********************************************
// GetDomainName
//
// Params: [out] BSTR * bstrDomainName
// Output: HRESULT
// Purpose: Retrieve the Domain DNS name.
********************************************/
HRESULT GetDomainName(BSTR * bstrDomainName)
{
HRESULT hr = S_OK;
IADsADSystemInfo *pADsys;
hr = CoCreateInstance(CLSID_ADSystemInfo,
NULL,
CLSCTX_INPROC_SERVER,
IID_IADsADSystemInfo,
(void**)&pADsys);
hr = pADsys->get_DomainDNSName(bstrDomainName);

if (pADsys)
pADsys->Release();
return hr;
}

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Searching/Displaying Objects Using CDOEX

Visual C++

Note The following example uses a file URL with the Exchange OLE DB (ExOLEDB) provider. The ExOLEDB provider also supports the HTTP URL scheme. Using the HTTP URL scheme allows both client and server applications to use a single URL scheme.
//Search and Display objects using CDO and ADO
//Modify the code where you see TODO and make sure the objects or properties exist

#include <activeds.h>
#include <stdio.h>
#include <conio.h>
#import <msado15.dll> no_namespace rename("EOF","adoEOF")
#import <cdoex.dll> no_namespace

struct StartOle {
   StartOle() { CoInitialize(NULL); }
   ~StartOle() { CoUninitialize(); }
} _inst_StartOle;

void dump_com_error(_com_error &e)
{
    printf("Oops - hit an error!\n");
    printf("\tCode = %08lx\n", e.Error());
    printf("\tCode meaning = %s\n", e.ErrorMessage());
    _bstr_t bstrSource(e.Source());
    _bstr_t bstrDescription(e.Description());
    printf("\tSource = %s\n", (LPCTSTR) bstrSource);
    printf("\tDescription = %s\n", (LPCTSTR) bstrDescription);
}

void SearchListObjects(_bstr_t strDomainName, _bstr_t strLocalPathOfSourceFolder, _bstr_t strSearchSql);
HRESULT GetDomainName(BSTR * bstrDomainName);

void main(void)
{
    _bstr_t strDomainName;
    _bstr_t strLocalPathOfSourceFolder;
    _bstr_t strSourceFolderUrl;
    _bstr_t strSearchSql;
    _bstr_t strUser;
   HRESULT hr = S_OK;
   BSTR bstrDomainDNSName;
   // Get your Domain Name.
   hr = GetDomainName(&bstrDomainDNSName);

    strDomainName = (_bstr_t)bstrDomainDNSName;
    strUser = "user1";  // TODO

    // Sample 1: List Appointments  in 'Calendar';
    strLocalPathOfSourceFolder = "MBX/" + strUser + "/Calendar";
    strSourceFolderUrl = "file://./backofficestorage/" + strDomainName + "/" + strLocalPathOfSourceFolder;

    // create the SQL query for the recordset (appointments)
    strSearchSql = "select ";
    strSearchSql = strSearchSql + "\"urn:schemas:mailheader:content-class\"";
    strSearchSql = strSearchSql + ", \"DAV:href\"";
    strSearchSql = strSearchSql + ", \"DAV:displayname\"";
    strSearchSql = strSearchSql + ", \"DAV:isfolder\"";
    strSearchSql = strSearchSql + ", \"DAV:iscollection\"";
    strSearchSql = strSearchSql + ", \"urn:schemas:httpmail:subject\"";
    strSearchSql = strSearchSql + " from scope ('shallow traversal of ";
    strSearchSql = strSearchSql + "\"" + strSourceFolderUrl + "\"" + "')";
    strSearchSql = strSearchSql + " WHERE \"DAV:ishidden\" = false";
    strSearchSql = strSearchSql + " AND \"DAV:isfolder\" = false";

    SearchListObjects(strDomainName, strLocalPathOfSourceFolder, strSearchSql);

    // Sample 2: List Contacts  in 'Ccontacts'
    strLocalPathOfSourceFolder = "MBX/" + strUser  + "/Contacts";
    strSourceFolderUrl = "file://./backofficestorage/" + \
                 strDomainName + "/" + strLocalPathOfSourceFolder;

    // create the SQL query for the recordset (appointments)
    strSearchSql = "select ";
    strSearchSql = strSearchSql + "\"urn:schemas:mailheader:content-class\"";
    strSearchSql = strSearchSql + ", \"DAV:href\"";
    strSearchSql = strSearchSql + ", \"DAV:displayname\"";
    strSearchSql = strSearchSql + ", \"DAV:isfolder\"";
    strSearchSql = strSearchSql + ", \"DAV:iscollection\"";
    strSearchSql = strSearchSql + ", \"urn:schemas:httpmail:subject\"";
    strSearchSql = strSearchSql + " from scope ('shallow traversal of ";
    strSearchSql = strSearchSql + "\"" + strSourceFolderUrl + "\"" + "')";
    strSearchSql = strSearchSql + " WHERE \"DAV:ishidden\" = false";
    strSearchSql = strSearchSql + " AND \"DAV:isfolder\" = false";

    SearchListObjects(strDomainName, strLocalPathOfSourceFolder, strSearchSql);

    // Sample 3: Travel all subfolders of 'MBX' under the user
    strLocalPathOfSourceFolder = "MBX/" + strUser;
    strSourceFolderUrl = "file://./backofficestorage/" + strDomainName + "/" + strLocalPathOfSourceFolder;

    // create the SQL query for the recordset (appointments)
    strSearchSql = "select ";
    strSearchSql = strSearchSql + "\"urn:schemas:mailheader:content-class\"";
    strSearchSql = strSearchSql + ", \"DAV:href\"";
    strSearchSql = strSearchSql + ", \"DAV:displayname\"";
    strSearchSql = strSearchSql + ", \"DAV:isfolder\"";
    strSearchSql = strSearchSql + ", \"DAV:iscollection\"";
    strSearchSql = strSearchSql + ", \"urn:schemas:httpmail:subject\"";
    strSearchSql = strSearchSql + " from scope ('shallow traversal of ";
    strSearchSql = strSearchSql + "\"" + strSourceFolderUrl + "\"" + "')";
    strSearchSql = strSearchSql + " WHERE \"DAV:ishidden\" = false";
    strSearchSql = strSearchSql + " AND \"DAV:isfolder\" = true";
    strSearchSql = strSearchSql + " AND \"DAV:iscollection\" = true";

    SearchListObjects(strDomainName, strLocalPathOfSourceFolder, strSearchSql);

}

/********************************
Search objects then display then if found

*********************************/
void SearchListObjects(_bstr_t strDomainName, _bstr_t strLocalPathOfSourceFolder, _bstr_t strSearchSql)
{
   _ConnectionPtr conn(_uuidof(Connection));
   _RecordsetPtr Rst(_uuidof(Recordset));
       _bstr_t strSourceFolderUrl;

   HRESULT hr = S_OK;

   try
   {
              // set the strURL to the location of the folders
              strSourceFolderUrl = "file://./backofficestorage/" + strDomainName + "/" + strLocalPathOfSourceFolder;
              printf("strSourceFolderUrl : %s\n", (char *)strSourceFolderUrl);

      // open connection
      conn->Provider = "Exoledb.DataSource";
      hr = conn->Open(strSourceFolderUrl,"","",0);

      if (conn->State == adStateOpen)
         printf("Connection Opened!\n");
      else
         printf("Connection failed!\n");

      // open Recordset
      hr = Rst->Open(strSearchSql,conn->ConnectionString,adOpenForwardOnly,adLockReadOnly,0);  //du test

      if (Rst->State == adStateOpen)
         printf("Rst Opened Successfully!\n");
      else
         printf("Rst Opened Failed!\n");

      // check if found any objects
      if (Rst->RecordCount == 0)
      {
         printf("No object found\n");
         return;
      }

              // now found some objects
      hr = Rst->MoveFirst();

      while (VARIANT_FALSE == Rst->adoEOF)
      {
                     _bstr_t strObjectUrl;
                     _bstr_t strContentClass;
                     bool boolIsCollection;

                     // retrieve some properties
         FieldsPtr Flds = Rst->GetFields();
         FieldPtr Fld = Flds->GetItem("DAV:href");
         strObjectUrl = (_bstr_t)(Fld->Value);

         Fld = Flds->GetItem("urn:schemas:mailheader:content-class");
         strContentClass = (_bstr_t)(Fld->Value);

         Fld = Flds->GetItem("DAV:iscollection");
         boolIsCollection = (bool)(Fld->Value);

         //printf("Content-clase = %s\n", (char *)strContentClass);

         // consider each situation
                     if (boolIsCollection)
         {
                 Fld = Flds->GetItem("DAV:displayname");
                printf("Folder : %s\n", (char *)(_bstr_t)(Fld->Value));

         }
         else{
            if (wcsicmp(strContentClass, (_bstr_t)"urn:content-classes:message") == 0)
            {
                            IMessagePtr pMsg(__uuidof(Message));
              IDataSourcePtr pDsrc;

              hr = pMsg->get_DataSource(&pDsrc);

              hr = pDsrc->Open((_bstr_t)strObjectUrl,
                                  NULL,
                     adModeReadWrite,
                     adFailIfNotExists,
                     adOpenSource,
                     "", "");

              // get the date received
              Flds = pMsg->GetFields();
                    Fld = Flds->GetItem("urn:schemas:httpmail:datereceived");  // TODO

                            printf("Message\n");
                           printf("Sender :%s\n", (char *)(_bstr_t)pMsg->Sender);   // TODO
                            printf("TimeReceived :%s\n\n", (char *)(_bstr_t)(Fld->Value));

              // clear up
              pDsrc = NULL;
              pMsg = NULL;

            }
            else if (wcsicmp(strContentClass, (_bstr_t)"urn:content-classes:person") == 0)
            {

                           IPersonPtr pPerson(__uuidof(Person));
              IDataSourcePtr pDsrc;

              hr = pPerson->get_DataSource(&pDsrc);

              hr = pDsrc->Open( (_bstr_t)strObjectUrl,
                                 NULL,
                    adModeReadWrite,
                    adFailIfNotExists,
                     adOpenSource,
                     "", "");

                           printf("Person\n");
                           printf("First Name :%s\n", (char *)(_bstr_t)pPerson->FirstName);   // TODO
                           printf("Last Name :%s\n", (char *)(_bstr_t)pPerson->LastName);   // TODO
                           printf("Title :%s\n", (char *)(_bstr_t)pPerson->Title);                       // TODO
                           printf("Company :%s\n\n", (char *)(_bstr_t)pPerson->Company);  // TODO

              // clear up
              pDsrc = NULL;
              pPerson = NULL;

            }
             else if (wcsicmp(strContentClass, (_bstr_t)"urn:content-classes:appointment") == 0)
            {
                           IAppointmentPtr pAppt(__uuidof(Appointment));
              IDataSourcePtr pDsrc;

              hr = pAppt->get_DataSource(&pDsrc);

              hr = pDsrc->Open( (_bstr_t)strObjectUrl,
                                NULL,
                   adModeReadWrite,
                   adFailIfNotExists,
                   adOpenSource,
                   "", "");

                           printf("Appointment\n");
                           printf("Subject :%s\n", (char *)(_bstr_t)pAppt->Subject);      // TODO
                           printf("Location :%s\n", (char *)(_bstr_t)pAppt->Location);  // TODO

              // retrieve the date using Fields
              Flds = pAppt->GetFields();

                  Fld = Flds->GetItem("urn:schemas:calendar:dtstart");
                           printf("StartTime :%s\n", (char *)(bstr_t)(Fld->Value));
                  Fld = Flds->GetItem("urn:schemas:calendar:dtend");
            printf("EndTime :%s\n\n", (char *)(bstr_t)(Fld->Value));

              // clear up
              pDsrc = NULL;
              pAppt = NULL;

            }
             else
            {
              printf("Else case = %s\n", (char *)strContentClass);
            }
         }

         Rst->MoveNext();
      }

      // close connections
      Rst->Close();
      conn->Close();

      // clear up
          Rst = NULL;
          conn = NULL;
   }
   catch(_com_error &e)
   {
       dump_com_error(e);
   }

}

/********************************************
// GetDomainName
//
// Params: [out] BSTR * bstrDomainName
// Output: HRESULT
// Purpose: Retrieve the Domain DNS name.
**********************************************/
HRESULT GetDomainName(BSTR * bstrDomainName)
{
HRESULT hr = S_OK;
IADsADSystemInfo *pADsys;
hr = CoCreateInstance(CLSID_ADSystemInfo,
NULL,
CLSCTX_INPROC_SERVER,
IID_IADsADSystemInfo,
(void**)&pADsys);
hr = pADsys->get_DomainDNSName(bstrDomainName);

if (pADsys)
pADsys->Release();
return hr;
}

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Modifying Objects Using CDOEX

Visual C++

Note The following example uses a file URL with the Exchange OLE DB (ExOLEDB) provider. The ExOLEDB provider also supports the HTTP URL scheme. Using the HTTP URL scheme allows both client and server applications to use a single URL scheme.
//Change folder name, modify appointments and contacts
//Modify the code where you see TODO and make sure the objects or properties exist

#include <activeds.h>
#include <stdio.h>
#include <conio.h>
#import <msado15.dll> no_namespace rename("EOF","adoEOF")
#import <cdoex.dll> no_namespace

struct StartOle {
   StartOle() { CoInitialize(NULL); }
   ~StartOle() { CoUninitialize(); }
} _inst_StartOle;

void dump_com_error(_com_error &e)
{
    printf("Oops - hit an error!\n");
    printf("\tCode = %08lx\n", e.Error());
    printf("\tCode meaning = %s\n", e.ErrorMessage());
    _bstr_t bstrSource(e.Source());
    _bstr_t bstrDescription(e.Description());
    printf("\tSource = %s\n", (LPCTSTR) bstrSource);
    printf("\tDescription = %s\n", (LPCTSTR) bstrDescription);
}

void ModifyObjects(_bstr_t strDomainName, _bstr_t strLocalPathOfSourceFolder, _bstr_t strSearchSql);
HRESULT GetDomainName(BSTR * bstrDomainName);

void main(void)
{
    _bstr_t strDomainName;
    _bstr_t strLocalPathOfSourceFolder;
    _bstr_t strSourceFolderUrl;
    _bstr_t strSearchSql;
    _bstr_t strUser;

          HRESULT hr = S_OK;
          BSTR bstrDomainDNSName;
          // Get your Domain Name.
          hr = GetDomainName(&bstrDomainDNSName);

             strDomainName = (_bstr_t)bstrDomainDNSName;

    strUser = "user1";  // TODO

    // Sample 1: List Appointments  in 'Calendar';
    strLocalPathOfSourceFolder = "MBX/" + strUser + "/Calendar";

    // create the SQL query for the recordset (appointments)
    strSourceFolderUrl = "file://./backofficestorage/" + strDomainName + "/" + strLocalPathOfSourceFolder;

    strSearchSql = "select ";
    strSearchSql = strSearchSql + "\"urn:schemas:mailheader:content-class\"";
    strSearchSql = strSearchSql + ", \"DAV:href\"";
    strSearchSql = strSearchSql + ", \"DAV:displayname\"";
    strSearchSql = strSearchSql + ", \"DAV:isfolder\"";
    strSearchSql = strSearchSql + ", \"DAV:iscollection\"";
    strSearchSql = strSearchSql + ", \"urn:schemas:httpmail:subject\"";
    strSearchSql = strSearchSql + " from scope ('shallow traversal of ";
    strSearchSql = strSearchSql + "\"" + strSourceFolderUrl + "\"" + "')";
    strSearchSql = strSearchSql + " WHERE \"DAV:ishidden\" = false";
    strSearchSql = strSearchSql + " AND \"DAV:isfolder\" = false";
    strSearchSql = strSearchSql + " AND \"urn:schemas:httpmail:subject\" = 'Test Appointment'";   // TODO

    ModifyObjects(strDomainName, strLocalPathOfSourceFolder, strSearchSql);

    // Sample 2: Modify the contacts with nickname "Small"  in 'Ccontacts'
    strLocalPathOfSourceFolder = "MBX/" + strUser  + "/Contacts";

    // create the SQL query for the recordset (appointments)
    strSourceFolderUrl = "file://./backofficestorage/" + \
                 strDomainName + "/" + strLocalPathOfSourceFolder;

    strSearchSql = "select ";
    strSearchSql = strSearchSql + "\"urn:schemas:mailheader:content-class\"";
    strSearchSql = strSearchSql + ", \"DAV:href\"";
    strSearchSql = strSearchSql + ", \"DAV:displayname\"";
    strSearchSql = strSearchSql + ", \"DAV:isfolder\"";
    strSearchSql = strSearchSql + ", \"DAV:iscollection\"";
    strSearchSql = strSearchSql + ", \"urn:schemas:contacts:nickname\"";
    strSearchSql = strSearchSql + " from scope ('shallow traversal of ";
    strSearchSql = strSearchSql + "\"" + strSourceFolderUrl + "\"" + "')";
    strSearchSql = strSearchSql + " WHERE \"DAV:ishidden\" = false";
    strSearchSql = strSearchSql + " AND \"DAV:isfolder\" = false";
    strSearchSql = strSearchSql + " AND \"urn:schemas:contacts:nickname\" = 'Small'";   // TODO

    ModifyObjects(strDomainName, strLocalPathOfSourceFolder, strSearchSql);

    // Sample 3: Modify the folder "TestFolder" name
    strLocalPathOfSourceFolder = "MBX/" + strUser + "/Outbox";

    // create the SQL query for the recordset (appointments)
    strSourceFolderUrl = "file://./backofficestorage/" + strDomainName + "/" + strLocalPathOfSourceFolder;

    strSearchSql = "select ";
    strSearchSql = strSearchSql + "\"urn:schemas:mailheader:content-class\"";
    strSearchSql = strSearchSql + ", \"DAV:href\"";
    strSearchSql = strSearchSql + ", \"DAV:displayname\"";
    strSearchSql = strSearchSql + ", \"DAV:isfolder\"";
    strSearchSql = strSearchSql + ", \"DAV:iscollection\"";
    strSearchSql = strSearchSql + ", \"urn:schemas:httpmail:subject\"";
    strSearchSql = strSearchSql + " from scope ('shallow traversal of ";
    strSearchSql = strSearchSql + "\"" + strSourceFolderUrl + "\"" + "')";
    strSearchSql = strSearchSql + " WHERE \"DAV:ishidden\" = false";
    strSearchSql = strSearchSql + " AND \"DAV:isfolder\" = true";
    strSearchSql = strSearchSql + " AND \"DAV:displayname\" = 'TestFolder'";   // TODO

    ModifyObjects(strDomainName, strLocalPathOfSourceFolder, strSearchSql);

}

/**********************************************
 Modify Objects and specially
- change folder name
- modify appointment and contact

***********************************************/

void ModifyObjects(_bstr_t strDomainName, _bstr_t strLocalPathOfSourceFolder, _bstr_t strSearchSql)
{
   _ConnectionPtr conn(_uuidof(Connection));
   _RecordsetPtr Rst(_uuidof(Recordset));
       _bstr_t strSourceFolderUrl;

   HRESULT hr = S_OK;

   try
   {
              // set the strURL to the location of the folders
              strSourceFolderUrl = "file://./backofficestorage/" + strDomainName + "/" + strLocalPathOfSourceFolder;
              printf("strSourceFolderUrl : %s\n", (char *)strSourceFolderUrl);

      // open connention
      conn->Provider = "Exoledb.DataSource";
      hr = conn->Open(strSourceFolderUrl,"","",0);

      if (conn->State == adStateOpen)
         printf("Connection Opened!\n");
      else
         printf("Connection failed!\n");

      // open recordset
      hr = Rst->Open(strSearchSql,conn->ConnectionString,adOpenForwardOnly,adLockOptimistic,0);  //du test

      if (Rst->State == adStateOpen)
         printf("Rst Opened Successfully!\n");
      else
         printf("Rst Opened Failed!\n");

              printf("Objects founded # = %d\n", Rst->RecordCount);

      // check if found any objects
      if (Rst->RecordCount == 0)
      {
                     printf("No object needs to be modified!\n");
         return;
      }

      // now found some objects
      hr = Rst->MoveFirst();

      _bstr_t strResult = "";
      while (VARIANT_FALSE == Rst->adoEOF)
      {
                    _bstr_t strObjectUrl;
                  _bstr_t strContentClass;
                  bool boolIsCollection;

                     // retrieve some properties
         FieldsPtr Flds = Rst->GetFields();
         FieldPtr Fld = Flds->GetItem("DAV:href");
         strObjectUrl = (_bstr_t)(Fld->Value);

         Fld = Flds->GetItem("urn:schemas:mailheader:content-class");
         strContentClass = (_bstr_t)(Fld->Value);

         Fld = Flds->GetItem("DAV:iscollection");
         boolIsCollection = (bool)(Fld->Value);

         //printf("Content-clase = %s\n", (char *)strContentClass);

                  if (boolIsCollection)
         {
                 Fld = Flds->GetItem("DAV:displayname");
                printf("Folder : %s\n", (char *)(_bstr_t)(Fld->Value));

                         _RecordPtr Rec(__uuidof(Record));
            _bstr_t strFolderNewName = "ModifedName";

                   // open the record
                   hr = Rec->Open((_variant_t)strObjectUrl,
                   conn->ConnectionString,
                  adModeReadWrite,
                  adFailIfNotExists,
                  adOpenSource,
                  L"", L"");

                   // use move to change the folder name
                   Rec->MoveRecord(strObjectUrl,
                                strSourceFolderUrl + "/"  + strFolderNewName,
                                "", "",
                                adMoveOverWrite,
                               false);

                        // close record
                   Rec->Close();

               //clear up
               Rec = NULL;

         }
         else{
            if (wcsicmp(strContentClass, (_bstr_t)"urn:content-classes:message") == 0)
            {
             // We will not modify Message but just check some properties at moment  // TODO
                            IMessagePtr pMsg(__uuidof(Message));
              IDataSourcePtr pDsrc;

              hr = pMsg->get_DataSource(&pDsrc);

              hr = pDsrc->Open((_bstr_t)strObjectUrl,
                                NULL,
                       adModeReadWrite,
                       adFailIfNotExists,
                       adOpenSource,
                       L"", L"");

              // get the date received
              Flds = pMsg->GetFields();
                    Fld = Flds->GetItem("urn:schemas:httpmail:datereceived");

                            printf("Message\n");
                            printf("Sender :%s\n", (char *)(_bstr_t)pMsg->Sender);
                            printf("TimeReceived :%s\n\n", (char *)(_bstr_t)(Fld->Value));

              // clear up
              pDsrc = NULL;
              pMsg = NULL;

            }
            else if (wcsicmp(strContentClass, (_bstr_t)"urn:content-classes:person") == 0)
            {

                            IPersonPtr pPerson(__uuidof(Person));
              IDataSourcePtr pDsrc;

              hr = pPerson->get_DataSource(&pDsrc);

              hr = pDsrc->Open( (_bstr_t)strObjectUrl,
                                NULL,
                      adModeReadWrite,
                      adFailIfNotExists,
                      adOpenSource,
                      L"", L"");

              // change a property directly
              pPerson->Title = (_bstr_t)"Developer";

              // change a property by using fields
              Flds = pPerson->GetFields();
              Fld = Flds->GetItem("urn:schemas:contacts:department");
              Fld->Value = (_bstr_t)"New department";
              Flds->Update();

              // update the changed properties
              pDsrc->Save();

              // clear the objects
              pDsrc = NULL;
              pPerson = NULL;

            }
             else if (wcsicmp(strContentClass, (_bstr_t)"urn:content-classes:appointment") == 0)
            {
                             IAppointmentPtr pAppt(__uuidof(Appointment));
              IDataSourcePtr pDsrc;

              hr = pAppt->get_DataSource(&pDsrc);

              hr = pDsrc->Open( (_bstr_t)strObjectUrl,
                                 NULL,
                        adModeReadWrite,
                        adFailIfNotExists,
                        adOpenSource,
                        L"",  L"");

              // change some properties
              pAppt->Subject = (_bstr_t)"New Subject";
              pAppt->Location = (_bstr_t)"New Location";
              pDsrc->Save();

              // clear up
              pDsrc = NULL;
              pAppt = NULL;

            }
             else
            {
              printf("Else case = %s\n", (char *)strContentClass);
            }
         }

         Rst->MoveNext();
      }

      // close connections
      Rst->Close();
      conn->Close();

      // clear up
      Rst = NULL;
          conn = NULL;

   }
   catch(_com_error &e)
   {
       dump_com_error(e);
   }
}

/*******************************************
// GetDomainName
//
// Params: [out] BSTR * bstrDomainName
// Output: HRESULT
// Purpose: Retrieve the Domain DNS name.
********************************************/
HRESULT GetDomainName(BSTR * bstrDomainName)
{
HRESULT hr = S_OK;
IADsADSystemInfo *pADsys;
hr = CoCreateInstance(CLSID_ADSystemInfo,
NULL,
CLSCTX_INPROC_SERVER,
IID_IADsADSystemInfo,
(void**)&pADsys);
hr = pADsys->get_DomainDNSName(bstrDomainName);

if (pADsys)
pADsys->Release();
return hr;
}

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Working with Item Properties

The following topics outline how to go about working with item properties.

Getting Item Property Values (WebDAV)

Printing Item Property Names, Types, and Values

Working with Multivalued Properties

Modifying Item Property Values (WebDAV)

Setting and Retrieving Custom Properties

Removing Properties (WebDAV)

Setting Multivalued Properties (WebDAV)

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Getting Item Property Values (WebDAV)

This example shows how you can manually construct the XML body of a PROPFIND WebDAV request. The request is for the DAV:displayname for a folder. After the request has been constructed, the code passes the XML string to an XMLHTTP Component Object Model (COM) object and sends the PROPFIND request to the server.

The following example shows what the request might look like (the code has been formatted for clarity):

PROPFIND /public/docs/ HTTP/1.1
Content-Type: text/xml;   charset="UTF-8"
Content-Length: XXX
Depth: 1
...

<?xml version="1.0" encoding="UTF-8"?>
<d:propfind xmlns:d="DAV:">
 <d:prop><d:displayname/></d:prop>
</d:propfind>

This example is provided mainly for illustration. It is easy to make errors when constructing XML streams manually, so you should use an XML Document Object Model (DOM) implementation to do so.

VBScript

<HTML>
<HEAD>
<META NAME="GENERATOR" Content="Microsoft Visual Studio 6.0">
<TITLE>Simple PROPFIND</TITLE>
</HEAD>
<BODY LANGUAGE="VBScript" onLoad="doXML">
<SCRIPT FOR=WINDOW LANGUAGE=VBSCRIPT>
<!--

Sub DoXML
Dim objX, strR, objXD, objDE
Set objX = CreateObject("Microsoft.XMLHTTP")
objX.Open "PROPFIND", "http://myServer/public/docs/", FALSE, "ADOMAIN\Administrator", ""
strR = "<?xml version='1.0'?>"
strR = strR & "<d:propfind xmlns:d='DAV:'>"
strR = strR & "<d:prop><d:displayname/></d:prop></d:propfind>"
objX.SetRequestHeader "Content-type:", "text/xml"
objX.SetRequestHeader "Depth", "1"
objX.send(strR)

set docback = objX.responseXML

Dim objNodeList
Set objNodeList = docback.getElementsByTagName("*")
For i = 0 TO (objNodeList.length -1)
  Set objNode = objNodeList.nextNode
  Document.Write("<b>" & objNode.NamespaceURI & " " & objNode.NodeName & "</b> - ")
  Document.Write(objNode.Text & "<hr>")
Next
End Sub

//-->
</SCRIPT>

<P> </P>

</BODY>
</HTML>

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Printing Item Property Names, Types, and Values

This example demonstrates how to print the name, type, and value for each of an item's properties. In this routine, a bound Microsoft® ActiveX® Data Objects (ADO) Record object is passed, the Fields collection for the Record is enumerated, and the type for each Field is echoed to the console. Where appropriate, the value for the property is also printed. Properties that are binary or arrays of bytes are not printed.

When binding to an item in this way, the list of properties present within the Fields collection is determined using the following information:

  • The value of the item's DAV:contentclass and the parent folder's schema scope. If the item's content class is not defined within the parent folder's schema scope, only the properties actually set for the item appear in the Fields collection. If the content class is defined within the parent folder's schema scope, all properties defined by this class appear within the Fields collection.

    Note All properties defined by the item's content class appear in the Fields collection, even if the properties have not been set (are empty).

  • The properties that are set on the item but are not defined by the item's content class. You can always get all properties set for an item, whether or not these properties are part of the item's content class definition.

VBScript

Sub printPropsAndType( Rec )

 If Not (VarType(Rec) = vbObject And TypeName(Rec) = "Record") Then
   Err.Raise  &H80070057 ' E_INVALIDARG
 End If

 Dim Flds
 Set Flds = Rec.Fields

 Dim vt

 For Each Fld in Flds
  vt = VarType(Fld.Value)
  WScript.Echo Fld.Name
  If vt = 14 Then
    WScript.Echo "  (Unsupported VARIANT type for VBScript)"
  Else
    WScript.Echo "  " & TypeName(Fld.Value)
  End If

  If IsArray(Fld.Value) Then
   WScript.Echo VarType(Fld.Value)
   If VarType(Fld.Value) = 14 Then
     WScript.Echo "  " & "<array of unprintable>"
   ElseIf Not IsPrintable(TypeName(Fld.Value)) Then
     WScript.Echo "  " & "<array of unprintable>"
   Else
     temp = Fld.Value
     For i = LBound(temp) to UBound(temp)
       WScript.Echo "  " & temp(i)
     Next
   End If
  Else
   If VarType(Fld.Value) = 14 Then
     Wscript.Echo "  " & "<value unprintable>"
   ElseIf Not IsPrintable(TypeName(Fld.Value)) Then
     Wscript.Echo "  " & "<value unprintable>"
   Else
     Wscript.Echo "  " & Fld.Value
   End If
  End If
  wscript.echo
 Next
End Sub

Function IsPrintable(sTypeName)

 dim result

 Select Case sTypeName
  Case "Object"
   result = False
  Case "Object()"
   result = False
  Case "Byte"
   result = False
  Case "Byte()"
   result = False
  Case "Null"
   result = False
  Case "Error"
   result = False
  Case "Error()"
   result = False
  Case Else
   result = True
 End Select

 IsPrintable = result
End Function

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Working with Multivalued Properties

Properties for items in the Web Storage System can have multiple values. In this case, you set or retrieve the property using an Array (SAFEARRAY). Even if the multivalued property has only one value, you still use an Array.

Each value in the array must be of the same type. For example, a property can be a multivalued array of Strings (string or BSTR) or Longs (i4 or long), but not both strings and integers.

The following example demonstrates how to set and retrieve multivalued properties for items.

VBScript

' Assume URL is defined and points to a folder.

Const adModeReadWrite = 3

Dim Rec
Dim Conn
Set Conn = CreateObject("ADODB.Connection")
Set Rec  = CreateObject("ADODB.Record")
Conn.Provider = "ExOLEDB.DataSource"

Conn.Open URL
Rec.Open URL, Conn, adModeReadWrite

Dim Flds
Set Flds = Rec.Fields

Dim rgBaseSchema
rgBaseSchema = Flds("urn:schemas-microsoft-com:exch-data:baseschema").Value

' ...

Flds("urn:schemas-microsoft-com:exch-data:expected-content-class").Value = _
  Array("urn:content-classes:item", "urn:schemas-domain-tld:content-classes:special")

Flds.Update

Visual Basic

' Reference to ActiveDs Type Library
' Reference to ActiveX Data Objects 2.5 Library

Sub MultiValPropsExample()

    Dim sUrl As String
    Dim Info As New ADSystemInfo
    Dim InfoNT As New WinNTSystemInfo

    sUrl = "http://" & InfoNT.ComputerName & "." & Info.DomainDNSName & _
            "/public/test_folder3/"

    Dim Conn As New ADODB.Connection
    Dim Rec As New ADODB.Record
    Conn.Provider = "ExOLEDB.DataSource"
    Conn.Open sUrl
    Rec.Open sUrl, Conn, adModeReadWrite

    Dim Flds As ADODB.Fields
    Set Flds = Rec.Fields

    Dim rgExpectedContClass As Variant
    rgExpectedContClass = Flds("urn:schemas-microsoft-com:exch-data:expected-content-class").Value

    If IsArray(rgExpectedContClass) Then
        For I = LBound(rgExpectedContClass) To UBound(rgExpectedContClass)
            Debug.Print rgExpectedContClass(I)
        Next I
        ' ...
    Else
        Debug.Print "Error...VarType for returned VARIANT:"
        Debug.Print VarType(rgExpectedContClass)
    End If

    Dim rgCCs(2) As Variant
    rgCCs(0) = "urn:content-classes:item"
    rgCCs(1) = "urn:schemas-domain-tld:content-classes:special"
    Flds("urn:schemas-microsoft-com:exch-data:expected-content-class").Value = rgCCs
    Flds.Update

End Sub

C++

#import <msado15.dll> no_namespace
#import "c:\program files\common files\microsoft shared\cdo\cdoex.dll" no_namespace
#include <iostream.h>

void setBaseSchema(bstr_t sFolderUrl) {

   _RecordPtr Rec(__uuidof(Record));
   _ConnectionPtr Conn(__uuidof(Connection));

   Conn->Provider = "ExOLEDB.DataSource";
   try {
      Conn->Open(sFolderUrl, bstr_t(), bstr_t(), -1);
   }
   catch(_com_error e) {
      cout << "Error opening connection." << endl;
      //..
      throw e;
   }

   wchar_t* url1 =   L"http://server/public/test_folder2";
   wchar_t* url2 =   L"http://server/public/test_folder3";
   wchar_t* url3 =   L"http://server/public/non_ipm_subtree/Schema";

   VARIANT      vVal;
   VariantInit(&vVal);
   vVal.vt = VT_ARRAY | VT_VARIANT;

   SAFEARRAY* psa  = NULL;
   psa = SafeArrayCreateVector(VT_VARIANT, 0, 3);
   if(psa == NULL) {
      // handle error here.
   }

   VARIANT* pVal;
   HRESULT hr = S_OK;
   hr = SafeArrayAccessData(psa, (void**)&pVal);
   if(FAILED(hr)) {
      // handle error
   }

   VariantInit(&(pVal[0]));
   pVal[0].vt = VT_BSTR;
   pVal[0].bstrVal = SysAllocString(url1);
   VariantInit(&(pVal[1]));
   pVal[1].vt = VT_BSTR;
   pVal[1].bstrVal = SysAllocString(url2);
   VariantInit(&(pVal[2]));
   pVal[2].vt = VT_BSTR;
   pVal[2].bstrVal = SysAllocString(url3);

   SafeArrayUnaccessData(psa);

   vVal.parray = psa;

   try {
      Rec->Open(sFolderUrl,
            variant_t((IDispatch*)Conn,true),
            adModeReadWrite,
            adFailIfNotExists,
            adOpenSource,
            bstr_t(),
            bstr_t());
   }
   catch(_com_error e) {
      cout << "Error opening item" << endl;
      //..
   }

   FieldsPtr Flds;
   Flds = Rec->Fields;
   FieldPtr Fld;
   Fld = Flds->Item["urn:schemas-microsoft-com:exch-data:baseschema"];
   Fld->Value = vVal;

   SafeArrayDestroy(psa);
   VariantClear(&vVal);
   psa = NULL;

   try {
      Flds->Update();
   }
   catch(_com_error e) {
      cout << "update failed" << endl;
      cout << e.Description() << endl;
   }

   // Now, read the props back and print the values...
   variant_t vBaseSchema;
   vBaseSchema = Flds->Item["urn:schemas-microsoft-com:exch-data:baseschema"]->Value;
   if( ! (vBaseSchema.vt == (VT_ARRAY | VT_VARIANT))) {
      cout << "Unexpected..." << endl;
      // handle error
   }

   hr = SafeArrayAccessData(vBaseSchema.parray, (void**)&pVal);
   if(FAILED(hr)) {
      cout << "access data failed!!" << endl;
   }

   cout << "Set the baseschema property for the folder at \r\n  " << sFolderUrl;
   cout << " \r\nto the following URLS: " << endl;
   cout << bstr_t(pVal[0].bstrVal) << endl;
   cout << bstr_t(pVal[1].bstrVal) << endl;
   cout << bstr_t(pVal[2].bstrVal) << endl;

   SafeArrayUnaccessData(vBaseSchema.parray);

}

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Modifying Item Property Values (WebDAV)

This example shows how to construct the body of a Web Storage System PROPFIND WebDAV request by using the MSXML 2.0 Component Object Model (COM) component. In the XMLDOM object model, you use the AppendChild method to create nodes and add them to the XML document. After the request body has been constructed as an XML DOM Document, you then pass a reference to an XMLHTTP COM object and send the PROPFIND request to the server.

The following example illustrates the results of an HTTP request (the code has been formatted for clarity):

PROPPATCH /public/docs/myFile.doc HTTP/1.1
Content-Type: text/xml;   charset="UTF-8"
Content-Length: XXX
...

<?xml version="1.0" encoding="UTF-8"?>
<d:propertyupdate xmlns:d="DAV:">
  <d:set>
   <d:prop>
     <o:Author
        xmlns:o="urn:schemas-microsoft-com:office:office"
      >
        Ray Zambroski
     </o:Author>
   </d:prop>
  </d:set>
</d:propertyupdate>

If the request was successful, a message box displays the XMLHTTP.StatusText property, followed by the XML of the XMLDOM object that is returned from the XMLHTTP object.

VBScript

<HTML>
<HEAD>
<META NAME="GENERATOR" Content="Microsoft Visual Studio 6.0">
<TITLE>PROPPATCH</TITLE>
</HEAD>
<BODY>

<SCRIPT FOR=window EVENT=onload LANGUAGE=VBScript>
<!--

Set req = CreateObject("Microsoft.XMLHTTP")
Set domin = CreateObject("Microsoft.XMLDOM")
Set domback = CreateObject("Microsoft.XMLDOM")

req.Open "PROPPATCH", "http://myServer/public/docs/myfile.doc", False, "TheDomain\Administrator", "thepassword"

req.SetRequestHeader "encoding", "utf-8"

req.setRequestHeader "Content-Type", "text/xml; charset=""UTF-8"""

Set oPi = domin.createProcessingInstruction("xml", "version='1.0'")
domin.appendChild(opi)

Set PUpdate = Domin.CreateNode(1, "d:propertyupdate", "DAV:")
domin.AppendChild PUpdate

Set DSet = Domin.CreateNode(1, "d:set", "DAV:")
PUpdate.AppendChild DSet

Set DProp = Domin.CreateNode(1, "d:prop", "DAV:")
DSet.AppendChild DProp

Set Author = Domin.CreateNode(1, "O:Author", "urn:schemas-microsoft-com:office:office")
DProp.AppendChild Author

Set AuthorName = Domin.CreateTextNode("Ray Zambroski")
Author.AppendChild AuthorName

MsgBox domin.XML, ,"IN: PROPPATCH"

req.Send Domin

MsgBox req.StatusText, ,"PROPPATCH"

Set domback = Req.ResponseXML
MsgBox domback.XML, ,"OUT: PROPPATCH"
//-->
</SCRIPT>

</BODY>
</HTML>

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Setting and Retrieving Custom Properties

The following example demonstrates how to set properties on items in the Web Storage System.

VBScript

<job id="custom_props">
<reference object="adodb.record"/>

<script language='vbscript'>

Dim InfoNT
Set InfoNT = CreateObject("WinNTSystemInfo")

SetProps "http://" & InfoNT.ComputerName & "/public/test_folder/test1.txt"
GetProps "http://" & InfoNT.ComputerName & "/public/test_folder/test1.txt"

Sub SetProps(sUrl)

    Dim Rec
    Set Rec = CreateObject("ADODB.Record")
    Dim Conn
    Set Conn = CreateObject("ADODB.Connection")
    Conn.Provider = "ExOLEDB.DataSource"
    Conn.Open sUrl
    Rec.Open sUrl, Conn, adModeReadWrite

    Dim Flds
    Set Flds = Rec.Fields
    With Flds
      .Item("urn:schemas-domain-tld:modified") = Now
      .Item("urn:schemas-domain-tld:status") = "Behind Schedule"
      .Item("urn:schemas-domain-tld:author") = "Paul West"
      .Item("urn:schemas-domain-tld:author-email") = """Paul west"" <pw@somewhere.microsoft.com>"
      .Item("urn:schemas-domain-tld:editor") = "Wendy Wheeler"
      .Item("urn:schemas-domain-tld:editor-email") = """Wendy Wheeler"" <ww@somewhere.microsoft.com>"
      .Update
    End With

End Sub

Sub GetProps(sUrl)

   ' This example shows how to retrieve custom property values
   ' set in the previous snippet.

    Dim Rec
    Set Rec = CreateObject("ADODB.Record")
    Dim Conn
    Set Conn = CreateObject("ADODB.Connection")
    Conn.Provider = "ExOLEDB.DataSource"
    Conn.Open sUrl
    Rec.Open sUrl, Conn, adModeReadWrite

    Dim Flds
    Set Flds = Rec.Fields
    Dim Props(10)
    Props(1) = "urn:schemas-domain-tld:modified"
    Props(2) = "urn:schemas-domain-tld:status"
    Props(3) = "urn:schemas-domain-tld:author"
    Props(4) = "urn:schemas-domain-tld:author-email"
    Props(5) = "urn:schemas-domain-tld:editor"
    Props(6) = "urn:schemas-domain-tld:editor-email"
    For I = 1 To 6
      WScript.Echo Props(I) & vbCrLf
      WScript.Echo Flds(Props(I))
    Next

End Sub
</script>
</job>

Visual Basic

Sub SetProps(sUrl)

    Dim Rec As New Record
    Dim Conn As New Connection
    Conn.Provider = "ExOLEDB.DataSource"
    Conn.Open sUrl
    Rec.Open sUrl, Conn, adModeReadWrite

    Dim Flds As Fields
    Set Flds = Rec.Fields
  With Flds
    .Item("urn:schemas-domain-tld:modified") = Now
    .Item("urn:schemas-domain-tld:status") = "Behind Schedule"
    .Item("urn:schemas-domain-tld:author") = "Paul West"
    .Item("urn:schemas-domain-tld:author-email") = """Paul west"" <pw@somewhere.microsoft.com>"
    .Item("urn:schemas-domain-tld:editor") = "Wendy Wheeler"
    .Item("urn:schemas-domain-tld:editor-email") = """Wendy Wheeler"" <ww@somewhere.microsoft.com>"
    .Update
  End With

End Sub

Sub GetProps(sUrl)

   ' This example shows how to retrieve custom property values
   ' set in the previous snippet.

    Dim Rec As New Record
    Dim Conn As New Connection
    Conn.Provider = "ExOLEDB.DataSource"
    Conn.Open sUrl
    Rec.Open sUrl, Conn, adModeReadWrite

    Dim Flds As Fields
    Set Flds = Rec.Fields
    Dim Props(10) As Variant
    Props(1) = "urn:schemas-domain-tld:modified"
    Props(2) = "urn:schemas-domain-tld:status"
    Props(3) = "urn:schemas-domain-tld:author"
    Props(4) = "urn:schemas-domain-tld:author-email"
    Props(5) = "urn:schemas-domain-tld:editor"
    Props(6) = "urn:schemas-domain-tld:editor-email"
    For I = 1 To 6
      Debug.Print Props(I) & vbCrLf
      Debug.Print Flds(Props(I))
    Next I

End Sub

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Removing Properties (WebDAV)

The following WebDAV request removes a property named http://schemas/myspace/someproperty.

PROPPATCH requesturi HTTP/1.1
HOST: host
Content-type: text/xml
Content-Length: 203

<?xml version="1.0"?>
<g:propertyupdate xmlns:g="DAV:">
<g:remove>
<g:prop>
<http://schemas/myspace/someproperty>
</g:prop>
</g:remove>
</g:propertyupdate>

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Setting Multivalued Properties (WebDAV)

The following WebDAV request sets three content classes to the value of a urn:schemas-microsoft-com:exch-data:expected-content-class property.

<?xml version="1.0"?>

<a:propertyupdate xmlns:a="DAV:" xmlns:d="urn:schemas-microsoft-com:exch-data:" xmlns:b="urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/" xmlns:c="xml:">
  <a:set>
    <a:prop>
      <d:expected-content-class b:dt="mv.string">
             <c:v>urn:content-classes:message</c:v>
             <c:v>urn:content-classes:myclass1</c:v>
             <c:v>urn:content-classes:item</c:v>
      </d:expected-content-class>
    </a:prop>
  </a:set>
</a:propertyupdate>

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Searching the Web Storage System

This section contains common search tasks used with the Web Storage System. The examples in this section use the Microsoft® ActiveX® Data Objects (ADO) 2.5 Component Object Model (COM) component running on the same computer as the Web Storage System.

The search condition scope for most of these tasks is a shallow traversal, which is the default scope if no scope is specified. The Simple Query programming task contains commented code to show how to explicitly specify a shallow traversal. You can also search subfolders using a deep traversal.

You can improve search performance by employing the following techniques:

  • Take advantage of Web Storage System property and full-text indexing.
  • Use relative URLs to improve performance and simplify coding.
  • Pass one ADO Connection object to routines that open record sets and process search results.
  • If you are searching on a property that you defined with a property definition, you should CAST its data type to a known XML data type to ensure that it will be recognizable by the Web Storage System. Custom strings and Boolean properties, however, do not require casting.
  • Use the RANK BY clause to sort results based on how frequently and where the queried strings appear in the indexed documents.
  • Use the ORDER BY clause to sort the returned recordset in ascending or descending order according to one or more properties specified.

This section consists of the following topics:

Simple Query

Specifying a Deep Traversal

Word and Character Matching

Specifying a Date Range

Getting Item Counts with GROUP BY

Enumerating Search Results

Searching Folders (WebDAV)

Searching Calendar Folders with WebDAV

Specifying Row Ranges in a Search

Rendering Search Results with XSL

Searching/Listing Items Using ADO

Searching/Deleting Using ADO

Modifying Objects Using CDOEX and ADO

Creating Search Folders

Related Topics

  • Web Storage System Search
  • Web Storage System SQL Reference

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Simple Query

The following example shows how to construct and run a query on the Web Storage System, the results of which are passed to a function that enumerates the search results.

VBScript

'Finds items from a sender
'Passes search result recordset to DoResults (see Enumerating Results)

'get computer and domain information
Set info   = CreateObject("ADSystemInfo")
Set infoNT = CreateObject("WinNTSystemInfo")
cName = infoNT.ComputerName
dName = info.DomainDNSName

'create connection object
Set Conn = CreateObject("ADODB.Connection")
Conn.Provider = "Exoledb.DataSource"

'URL for connection object
'is at the virtual directory root
cURL = "http://" & _
      cName & "." & _
      dName & "/" & _
      "public"

Conn.Open cURL

'relative URL is the folder to search
relURL = "Reports"

sender = "Jane Clayton"

FindMsgsFrom sender, relURL, Conn

Sub FindMsgsFrom(sender, relURL, Conn)

     Const adErrNoCurrentRecord = 3021

     Set rs = CreateObject("ADODB.Recordset")

     'construct the SQL query
     strQ = "SELECT ""urn:httpmail:subject"" "
     strQ = strQ & "FROM """ & relURL & """ "

     '* ------
     '* A shallow traversal is the default scope. To explicitly
     '* specify a shallow traversal, the code would be:
     '* 'strQ = strQ & "FROM scope('shallow traversal of """ & strURL & """ ')"
     '*-------

     strQ = strQ & "WHERE ""urn:schemas:httpmail:sendername"" = '" & sender & "'"

     Rs.Open strQ, Conn

     'If empty recordset, return error
     'If successful call DoResults routine passing the recorset
     If Rs.EOF = True Then
          On Error Resume Next
          Err.Raise adErrNoCurrentRecord
          Response.Write "No items found, run another query."
     Else
          Response.Write "Success! Found " & Rs.RecordCount
          DoResults Rs
     End If
     Rs.Close

End Sub

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Specifying a Deep Traversal

A deep traversal is a scope that includes any and all subfolders. You cannot perform a deep traversal in the MAPI client public information store installed by Microsoft® Exchange 2000 Server, but you can perform deep traversals in private stores and in any new public folder tree.

VBScript

'Finds items from a sender, searching subfolders
'Passes search result recordset to DoResults (see Enumerating Results)

'get computer and domain information
Set info   = CreateObject("ADSystemInfo")
Set infoNT = CreateObject("WinNTSystemInfo")
cName = infoNT.ComputerName
dName = info.DomainDNSName

'create connection object
Set Conn = CreateObject("ADODB.Connection")
Conn.Provider = "Exoledb.DataSource"

'URL for connection object
'is at the virtual directory root
cURL = "http://" & _
      cName & "." & _
      dName & "/" & _
      "public"

Conn.Open cURL

'relative URL is the folder to search
relURL = "Reports"

sender = "Jane Clayton"

FindMsgsFrom sender, relURL, Conn

Sub FindMsgsFrom(sender, relURL, Conn)

     Const adErrNoCurrentRecord = 3021

     Set rs = CreateObject("ADODB.Recordset")

     'construct the SQL query, note the scope for deep traversal
     strQ = "SELECT ""urn:httpmail:subject"" "
     strQ = strQ & "FROM scope('deep traversal of """ & strURL & """ ')"
     strQ = strQ & "WHERE ""urn:schemas:httpmail:sendername"" = '" & sender & "'"

     Rs.Open strQ, Conn

     'If empty recordset, return error
     'If successful call DoResults routine passing the recorset
     If Rs.EOF = True Then
          On Error Resume Next
          Err.Raise adErrNoCurrentRecord
          Response.Write "No items found, run another query."
     Else
          Response.Write "Success! Found " & Rs.RecordCount
          DoResults Rs
     End If
     Rs.Close

End Sub

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Word and Character Matching

You can find items based on word and character matches of a specified search string. The example shows how to construct a Structured Query Language (SQL) query using the predicates in the following table.

Predicate | Usage
CONTAINS | Finds words in the order specified, such as “Romeo and Juliet.”
FREETEXT | Finds one or more words specified, such as “apples oranges pears.”
FORMSOF | Finds word variations, such as “gardening” and “garden.”
LIKE | Finds characters that match a specified string. The percent character (%) matches any or no characters adjacent to the specified string. For example, "%he ca%" matches "the cat."

VBScript

'Finds items based on CONTAINS, FREETEXT, FORMS, or LIKE predicate
'This example uses FREETEXT to find reports with names of cities
'Passes search result recordset to DoResults (see Enumerating Results)

'get computer and domain information
Set info   = CreateObject("ADSystemInfo")
Set infoNT = CreateObject("WinNTSystemInfo")
cName = infoNT.ComputerName
dName = info.DomainDNSName

'create connection object
Set Conn = CreateObject("ADODB.Connection")
Conn.Provider = "Exoledb.DataSource"

'URL for connection object
'is at the virtual directory root
cURL = "http://" & _
      cName & "." & _
      dName & "/" & _
      "public"

Conn.Open cURL

'relative URL is the folder to search
relURL = "Reports/FieldOffices"

'search specification variable
searchspec = "Tokyo London Bogata Honolulu Cairo Sydney Chicago"

'predicate to use in search
predicate = "FREETEXT"

FindSearchSpec searchspec, predicate, relURL, Conn

Sub FindSearchSpec(sender, relURL, Conn)

     Const adErrNoCurrentRecord = 3021

     Set rs = CreateObject("ADODB.Recordset")

     'construct the SQL query
     strQ = "SELECT ""urn:httpmail:subject"" "
     strQ = strQ & "FROM """ & relURL & """ "

     'Construct a query based on the search predicate.
     Select Case predicate
          Case "CONTAINS"
               strQ = strQ & "WHERE CONTAINS(*, '" & Chr(34) & searchspec & Chr(34) & "') "
          Case "FREETEXT"
               strQ = strQ & "WHERE FREETEXT(*, '" & Chr(34) & searchspec & Chr(34) & "') "
          Case "LIKE"
               strQ = strQ & "WHERE ""urn:schemas:httpmail:textdescription"" LIKE '" & searchspec & "'"
          Case "FORMSOF"
               strQ = strQ & "WHERE CONTAINS('FORMSOF(INFLECTIONAL," & Chr(34) & searchspec & Chr(34) & ")')"
          Case Else
               strQ = strQ & "WHERE CONTAINS(*, '" & Chr(34) & searchspec & Chr(34) & "') "
     End Select

     Rs.Open strQ, Conn

     'If empty recordset, return error
     'If successful call DoResults routine passing the recorset
     If Rs.EOF = True Then
          On Error Resume Next
          Err.Raise adErrNoCurrentRecord
          Response.Write "No items found, run another query."
     Else
          Response.Write "Success! Found " & Rs.RecordCount
          DoResults Rs
     End If
     Rs.Close

End Sub

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Specifying a Date Range

This example filters for items based on a date range.

Because Web Storage System date values use the DBTYPE_TIMESTAMP data type, you must include an exact time specification to match a particular date. For example, the following WHERE clause will not match items created on 2000-04-05:

WHERE "DAV:creationdate" = '2000-04-05'

To match, the date must be adjusted from local time to UTC (because dates are stored in UTC), and then converted to Industry Standards Organization (ISO) date format (yyyy-mm-ddThh:mm:ssZ). Finally, the date must be CAST to the DateTime data type, as shown in the following WHERE clause:

WHERE "DAV:creationdate" = CAST("2000-04-05T01:00:00Z" as 'dateTime')

Note that the "dateTime" must be used with a capital T in order to work. A practical way to match a date is to define the range between the day before and the day after, as shown in this clause:

WHERE "DAV:creationdate" > CAST("2000-04-04T01:00:00Z" as 'dateTime') AND "DAV:creationdate" < CAST("2000-04-06T01:00:00Z" as 'dateTime')

VBScript

'Finds items matching a date range
'Passes search result recordset to DoResults (see Enumerating Results)

'get computer and domain information
Set info   = CreateObject("ADSystemInfo")
Set infoNT = CreateObject("WinNTSystemInfo")
cName = infoNT.ComputerName
dName = info.DomainDNSName

'create connection object
Set Conn = CreateObject("ADODB.Connection")
Conn.Provider = "Exoledb.DataSource"

'URL for connection object
'is at the virtual directory root
cURL = "http://" & _
      cName & "." & _
      dName & "/" & _
      "public"

Conn.Open cURL

'relative URL is the folder to search
relURL = "Reports"

'date range variable:
DateRng = " > CAST(""2000-06-12T01:00:00Z"" as 'dateTime')"

FindMsgsByDate relURL, DateRng, Conn

Sub FindMsgsByDate(relURL, DateRng, Conn)

     Const adErrNoCurrentRecord = 3021

     Set rs = CreateObject("ADODB.Recordset")

     'construct the SQL query
     strQ = "SELECT ""urn:httpmail:subject"" "
     strQ = strQ & "FROM """ & relURL & """ "

     strQ = strQ & "WHERE ""urn:schemas:httpmail:datereceived"" " & DateRng

     Rs.Open strQ, Conn

     'If empty recordset, return error
     'If successful call DoResults routine passing the recorset
     If Rs.EOF = True Then
          On Error Resume Next
          Err.Raise adErrNoCurrentRecord
          Response.Write "No items found, run another query."
     Else
          Response.Write "Success! Found " & Rs.RecordCount
          DoResults Rs
     End If
     Rs.Close

End Sub

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Getting Item Counts with GROUP BY

You can use the GROUP BY clause to get a tally of specific items, such as the number of messages with low, normal, or high importance. The DAV:visiblecount property contains the total for each group in the returned record set.

Note Using the GROUP BY query produces a recordset that does not support Microsoft® ActiveX® Data Objects (ADO) bookmarks. Attempts to use methods that are only available for Recordsets that support bookmarks, such as the Recordset.Clone method, on a Recordset generated with the GROUP BY predicate, will return an error.

The property values shown in the following table would return a tally of 3 low-importance, 207 normal-importance, and 27 high-importance, messages.

Property | Value
DAV:visiblecount | 3
urn:schemas:httpmail:importance | 0 (low importance)
DAV:visiblecount | 207
urn:schemas:httpmail:importance | 1 (normal importance)
DAV:visiblecount | 27
urn:schemas:httpmail:importance | 2 (high importance)

VBScript

'Tallies number of high, normal, and low importance msgs

'get computer and domain information
Set info   = CreateObject("ADSystemInfo")
Set infoNT = CreateObject("WinNTSystemInfo")
cName = infoNT.ComputerName
dName = info.DomainDNSName

'create connection object
Set Conn = CreateObject("ADODB.Connection")
Conn.Provider = "Exoledb.DataSource"

'URL for connection object
'is at the virtual directory root
cURL = "http://" & _
      cName & "." & _
      dName & "/" & _
      "exchange/userA"

Conn.Open cURL

'relative URL is the folder to search
relURL = "Inbox"

TallyMsgsByImportance relURL, Conn

Sub TallyMsgsByImportance(relURL, Conn)

     Const adErrNoCurrentRecord = 3021

     Set rs = CreateObject("ADODB.Recordset")

     'construct the SQL query
     strQ = "SELECT ""DAV:visiblecount"", "
     strQ = strQ & " ""urn:schemas:httpmail:importance"" "
     strQ = strQ & "FROM """ & relURL & """ "
     strQ = strQ & "GROUP BY ""urn:schemas:httpmail:importance"" "

     Rs.Open strQ, Conn
     'If empty recordset, return error
     'If successful, display results
     If Rs.EOF = True Then
               On Error Resume Next
               Err.Raise adErrNoCurrentRecord
               WScript.Echo "No items found, run another query."
          Else
               Rs.MoveFirst
               Do Until Rs.EOF
               Select Case Rs("urn:schemas:httpmail:importance")
                    Case 2
                         strI = "High"
                    Case 1
                         strI = "Normal"
                    Case 0
                         strI = "Low"
               End Select
               WScript.Echo Rs("DAV:visiblecount") & " " & strI & " importance messages"
                    Rs.MoveNext
               Loop
     End If
     Rs.Close

End Sub

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Enumerating Search Results

This example shows how to process a returned record set, accommodating for multivalued and null properties, and how to render the results.

VBScript

'writes property values from a recordset (Rs)
'returned from a SQL query

'The DoResults function writes an HTML table
'for each record (item) in the recordset. In that table
'each property and value are written to a table cell,
'accommodating for null and multivalued properties.

Function DoResults(Rs)
    'If empty recordset, return error
    If Rs.EOF = True Then
     On Error Resume Next
     Err.Raise adErrNoCurrentRecord
     Response.Write "<br><FONT FACE=Arial SIZE=2>No items found, run another query.<p>"
     Else
          Rs.MoveFirst
          Do Until Rs.EOF
         'Create a HTML table for each record, make table headings stand out
         Response.Write "<FONT FACE=Arial SIZE=2><TABLE BORDER=1 cellpadding=5 cellspacing=5>"
         Response.Write "<TR><TH bgcolor=#0000ff><FONT color=#ffffff>Property</TH>"
         Response.Write "<TH bgcolor=#0000ff><FONT color=#ffffff>Value</TH></TR>"

         For Each f In Rs.Fields
            'for every field in the record
            Response.Write "<TR><TD><FONT SIZE=1>"
            Response.Write f.Name
            Response.Write "</TD><TD><FONT SIZE=1>"

            'accommodate null and multivalued properties
            If Not IsNull(f.Value) Then
                If IsArray(f.Value) Then
                   'a multi-valued  property
                  Dim V
                  For Each V In f.Value
                     On Error Resume Next
                     Response.Write(V & "<br>")
                  Next
               Else
                  On Error Resume Next
                  Response.Write f.Value
               End If
            Else
               'Field is null
               Response.Write "Null"
            End If
            Response.Write "</TD></TR>"
            Next
           Response.Write "</TABLE><br><hr><br>"
            Rs.MoveNext
        Loop
   End If
End Function

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Searching Folders (WebDAV)

This topic shows how to construct and send an WebDAV SEARCH request. The Structured Query Language (SQL) query is packaged as a value of an XML element that is sent to the server by using the XMLHTTP Component Object Model (COM) component.

The following example shows an HTTP search request:

SEARCH /public/folder1/ HTTP/1.1
Content-Type: text/xml
Content-Length: XXX
...

<?xml version="1.0"?>
<D:searchrequest xmlns:D = "DAV:" >
   <D:sql>
SELECT "dav:displayname", "urn:schemas:mailheader:textdescription"  FROM "http://myserver/vroot/folder1/"') where "DAV:ishidden" = false AND "DAV:isfolder" = false
   </D:sql>
</D:searchrequest>

See Web Storage System SQL Reference for supported SQL grammar syntax, indexed properties, unsupported SQL, and other search reference topics.

You can get search result values by manipulating the returned DOMDocument object. Use its getItemsbyTagName method to create a collection of nodes containing values for one of the properties in your SQL SELECT statement. The method is demonstrated in the task.

The prefix for the property, such as ‘d’ in <d:yourproperty>, is not entirely predictable; for more information, see Property Names and WebDAV.

VBScript

Sub Search

   set doc = createobject("microsoft.xmldom")
   set docback = createobject("microsoft.xmldom")
   dim strURL
   strURL = "http://myServer1/public/folder1/"
   set pi = doc.createProcessingInstruction("xml","version=""1.0""")
   doc.appendChild pi

   set node = doc.createNode(1,"searchrequest","DAV:")
   set doc.documentElement = node

   set node2 = doc.createNode(1,"sql","DAV:")
   node.appendChild node2
   set query = doc.createTextNode("select ""DAV:displayname"" from """ & strURL & """ WHERE CONTAINS(*,'""1998 Tax Return""')")
   node2.appendChild query

   set req = createobject("microsoft.xmlhttp")
   req.open "SEARCH", strURL, false, "NYCDomain\Administrator", "pw4me"
   req.setrequestheader "Translate", "f"
   req.setrequestheader "Content-Type", "text/xml"
   req.setrequestheader "Depth", "0"
   req.send doc

   set docback = req.responseXML

   'save the XML to disk to study
   docback.Save "d:\xml\docback.xml"

   Dim objNodeList

   'Typically the DAV namespace get the 'a' prefix.
   'If specifying multiple properties in a search
   'examine the returned XML beforehand to determine prefixes for your code

   Set objNodeList = docback.getElementsByTagName("a:displayname")
   For i = 0 To (objNodeList.length -1)
     Set objNode = objNodeList.nextNode
     Document.Write(objNode.Text & "<hr>")
   Next

   '******
   '*  If you also selected urn:schemas:httpmail:sendername in your SQL,
   '*  the code to get the values might be like this:
   '*
   '*     Set objNodeList2 = docback.getElementsByTagName("d:sendername")
   '*     For i = 0 To (objNodeList2.length -1)
   '*        Set objNode = objNodeList2.nextNode
   '*        Document.Write(objNode.Text & "<hr>")
   '*    Next
   '*
   '******

End Sub

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Searching Calendar Folders with WebDAV

This topic shows the WebDAV SEARCH query to search for calendar folders. See Searching Folders (WebDAV) for how to construct the query and to enumerate its results.

SEARCH /exchange/kwc2/calendar/ HTTP/1.1
Host: wil2
Content-Type: text/xml
Content-Length: 942

<?xml version="1.0"?>
<g:searchrequest xmlns:g="DAV:">
<g:sql> Select "urn:schemas:calendar:location" AS location,
"urn:schemas:httpmail:subject" AS subject,
"urn:schemas:calendar:dtstart" AS dtstart,
"urn:schemas:calendar:dtend" AS dtend,
"urn:schemas:calendar:busystatus" AS busystatus,
"urn:schemas:calendar:instancetype" AS instancetype,
"urn:schemas:calendar:alldayevent" AS alldayevent
FROM Scope('SHALLOW TRAVERSAL OF ""')
WHERE NOT "urn:schemas:calendar:instancetype" = 1
AND "DAV:contentclass" = 'urn:content-classes:appointment'
AND "urn:schemas:calendar:dtend" &gt; '1999/09/27 00:00:00'
AND "urn:schemas:calendar:dtstart" &lt; '2001/09/28 00:00:00'
ORDER BY "urn:schemas:calendar:dtstart" ASC

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Specifying Row Ranges in a Search

By including a range header in a WebDAV search request, you can obtain selected ranges in your search result using a variety of patterns, for example:

Range: rows=20-39
Range: rows=0-5, 10-15, 20-25, 30-35

For more examples, see Range Header in the Web Storage System Structured Query Language (SQL) reference.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Rendering Search Results with XSL

You can use the XSL capabilities of the MSXML 2.0 Component Object Model (COM) component to render the results of a PROPFIND method.

The following example uses a simple XSL style sheet to transform the XML body returned by the PROPFIND command into HTML for display in a browser.

JScript

<html>

<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
<meta name="GENERATOR" content="Microsoft FrontPage 4.0">
<meta name="ProgId" content="FrontPage.Editor.Document">
<title>Demo DAV Request</title>
<meta name="Microsoft Theme" content="none, default">
</head>

<xml id=calxsl>
<xsl:template   xmlns:xsl="uri:xsl" xmlns:d="DAV:">
<table
      id="thetable"
      onclick="clickrow();"
      border="4"
      width="100%"
      style="border-style: groove"
      cellspacing="0" bordercolor="#808080" bordercolorlight="#808080" bordercolordark="#000080">
  <tr>
    <td width="25%" onclick="resort(0, 'd:displayname');" bgcolor="silver"><font face="Tahoma" size="1"><b>Name</b></font></td>
    <td width="25%" onclick="resort(1, 'd:propstat/d:prop/d:creationdate');" bgcolor="silver"><font face="Tahoma" size="1"><b>Creation Date</b></font></td>
    <td width="25%" onclick="resort(2, 'd:propstat/d:prop/d:getlastmodified');" bgcolor="silver"><font face="Tahoma" size="1"><b>Last Modified</b></font></td>
  </tr>
  <xsl:for-each select="d:multistatus/d:response" order-by="d:href">
  <tr>
     <td><xsl:value-of select="d:href" /></td>
     <td><xsl:for-each select="d:propstat/d:prop/d:creationdate">
                 <xsl:eval>this.nodeTypedValue</xsl:eval></xsl:for-each></td>
     <td><xsl:value-of select="d:propstat/d:prop/d:getlastmodified" /></td>
  </tr>
  </xsl:for-each>

</table>
</xsl:template>
</xml>

<body>
<h1>Simple DAV request</h1>

<p>URL: <INPUT type="text" id=urlid name=urlid value="http://myServer1/" size=128></p>
<p>Depth: <SELECT id=depthid name=depthid>
<OPTION value="0">0</OPTION>
<OPTION value="1" SELECTED>1</OPTION>
<OPTION value="1,noroot">1,noroot</OPTION>
<OPTION value="infinity">infinity</OPTION>
</SELECT><INPUT type="button" value="Go" id=button1 name=button1 onclick="update()"></p>

<div id=xsldest>
</div>

<script>

function clickrow()
{
   src = event.srcElement;
   while(src.tagName != "TR")
      src = src.parentElement;
   if(src == thetable.rows[0])
      return;
   for(i=0; i < thetable.rows.length; i++)
   {
      onerow = thetable.rows[i];
      for(j = 0; j < onerow.cells.length; j++)
      {
         onecell = onerow.cells[j];
         onecell.style.backgroundColor = "white";
         onecell.style.color = "black";
      }
   }
   for(j = 0; j < src.cells.length; j++)
   {
      onecell = src.cells[j];
      onecell.style.backgroundColor = "black";
      onecell.style.color = "white";
   }
}

function resort(col, sortby)
{
   thenode = calxsl.selectSingleNode("xsl:template/table/xsl:for-each");
   thenode.setAttribute("order-by", sortby);
   xsldest.innerHTML = thexml.transformNode(calxsl.documentElement);
   therow = thetable.rows[0];
   therow.cells[col].style.backgroundColor = "gray";
}

</script>

<script>

var request;
var thexml;

function dostatechange()
{
   if(request == null || request.readystate != 4)
      return;
   if(request.status != 207)
   {
      xsldest.innerText = "Error, status = " + request.status + " " + request.statusText;
   }
   else
   {
      thexml = request.responseXML;
      xsldest.innerHTML = thexml.transformNode(calxsl.documentElement);
   }
   request = null;
}

function update()
{
   request = new ActiveXObject("microsoft.xmlhttp");
   request.open("PROPFIND", urlid.value, true);
   request.setRequestHeader("depth", depthid.value   );
   request.onreadystatechange = dostatechange;
   xsldest.innerHTML = "<h4>loading...</h4>";
   request.send("");
}

update();

</script>

</body>

</html>

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Searching/Listing Items Using ADO

Visual Basic

Note The following example uses a file URL with the Exchange OLE DB (ExOLEDB) provider. The ExOLEDB provider also supports the HTTP URL scheme. Using the HTTP URL scheme allows both client and server applications to use a single URL scheme.
'Searchnig/Listing Items using ADO
'This sample shows how to search objects
'
'Make reference to the ADO 2.5 library
'Make reference to Active DS Typy Library

     Private Sub SearchItems()
Dim strDomainName As String
Dim strUser As String

Dim strPathOfSourceFolder As String
Dim strSourceFolderUrl As String
Dim strSearchSql As String

' specify the domain and user
strDomainName = GetDomainDNSName()
strUser = "user1"

' Sample 1: List Appointments in 'Calendar'
strPathOfSourceFolder = "MBX/" & strUser & "/Calendar"

strSourceFolderUrl = "file://./backofficestorage/" & _
strDomainName & "/" & strPathOfSourceFolder

' create the SQL query for the recordset (appointments)
strSearchSql = "select "
strSearchSql = strSearchSql & " ""urn:schemas:mailheader:content-class"""
strSearchSql = strSearchSql & ", ""DAV:href"""
strSearchSql = strSearchSql & ", ""DAV:displayname"""
strSearchSql = strSearchSql & ", ""DAV:isfolder"""
strSearchSql = strSearchSql & ", ""DAV:iscollection"""
strSearchSql = strSearchSql & ", ""urn:schemas:httpmail:subject"""
strSearchSql = strSearchSql & " from scope ('shallow traversal of " & Chr(34)
strSearchSql = strSearchSql & strSourceFolderUrl & """') "
strSearchSql = strSearchSql & " WHERE ""DAV:ishidden"" = false"
strSearchSql = strSearchSql & " AND ""DAV:isfolder"" = false"

Call SearchListObjects(strDomainName, strPathOfSourceFolder, strSearchSql)

' Sample 2: List Contacts in 'Ccontacts'
strPathOfSourceFolder = "MBX/" & strUser & "/Contacts"

strSourceFolderUrl = "file://./backofficestorage/" & _
strDomainName & "/" & strPathOfSourceFolder

' create the SQL query for the recordset (appointments)
strSearchSql = "select "
strSearchSql = strSearchSql & " ""urn:schemas:mailheader:content-class"""
strSearchSql = strSearchSql & ", ""DAV:href"""
strSearchSql = strSearchSql & ", ""DAV:displayname"""
strSearchSql = strSearchSql & ", ""DAV:isfolder"""
strSearchSql = strSearchSql & ", ""DAV:iscollection"""
strSearchSql = strSearchSql & ", ""urn:schemas:httpmail:subject"""
strSearchSql = strSearchSql & " from scope ('shallow traversal of " & Chr(34)
strSearchSql = strSearchSql & strSourceFolderUrl & """') "
strSearchSql = strSearchSql & " WHERE ""DAV:ishidden"" = false"
strSearchSql = strSearchSql & " AND ""DAV:isfolder"" = false"

'Call SearchListObjects(strDomainName, strPathOfSourceFolder, strSearchSql)

' Sample 3: List Travel all subfolders of 'MBX' under the user
'strPathOfSourceFolder = "MBX/" & strUser

strPathOfSourceFolder = "MBX/" & strUser & "/Deleted Items"

strSourceFolderUrl = "file://./backofficestorage/" & _
strDomainName & "/" & strPathOfSourceFolder

' create the SQL query for the recordset (appointments)
strSearchSql = "select "
strSearchSql = strSearchSql & " ""urn:schemas:mailheader:content-class"""
strSearchSql = strSearchSql & ", ""DAV:href"""
strSearchSql = strSearchSql & ", ""DAV:displayname"""
strSearchSql = strSearchSql & ", ""DAV:isfolder"""
strSearchSql = strSearchSql & ", ""DAV:iscollection"""
strSearchSql = strSearchSql & " from scope ('shallow traversal of " & Chr(34)
strSearchSql = strSearchSql & strSourceFolderUrl & """') "
strSearchSql = strSearchSql & " WHERE ""DAV:ishidden"" = false"
strSearchSql = strSearchSql & " AND ""DAV:isfolder"" = true" 'can be omited
strSearchSql = strSearchSql & " AND ""DAV:iscollection"" = true"

Call SearchListObjects(strDomainName, strPathOfSourceFolder, strSearchSql)

End Sub

Private Sub SearchListObjects(strDomainName As String, strLocalPathOfSourceFolder As String, strSearchSql As String)
Dim Rec As New ADODB.Record
Dim Rst As New ADODB.Recordset
Dim strSourceFolderUrl As String

' set the URL to the location of the folder
strSourceFolderUrl = "file://./backofficestorage/" & _
strDomainName & "/" & strLocalPathOfSourceFolder

' open record
Rec.Open strSourceFolderUrl, , adModeReadWrite 'Move needs parameter adModeReadWrite

' open recordset - a list of objects
Rst.Open strSearchSql, Rec.ActiveConnection

' check see if fund any objects
If Rst.RecordCount = 0 Then
Debug.Print "No objects found!"
Exit Sub
End If

' Now found some objects
Rst.MoveFirst
Do While Not Rst.EOF

Dim strObjectUrl As String
Dim strContentClass As String

' retrieve some propertied
strObjectUrl = Rst.Fields("DAV:href")
strContentClass = Rst.Fields("urn:schemas:mailheader:content-class")
Debug.Print "ContectClass : " & strContentClass

If Rst.Fields("DAV:iscollection") = True Then
Debug.Print "FolderName : " & Rst.Fields("DAV:displayname")

'Retrieve Folder Type property
Dim iFolder As New CDO.Folder
iFolder.DataSource.Open strObjectUrl

Debug.Print "FolderType : " & iFolder.Fields("http://schemas.microsoft.com/exchange/outlookfolderclass") & vbLf

Set iFolder = Nothing
Else
Select Case strContentClass
Case "urn:content-classes:message"
Dim iMessage As New CDO.Message
iMessage.DataSource.Open strObjectUrl

' display some properties
Debug.Print "Message" & vbLf & _
"Sender: " & iMessage.Sender & vbLf & _
"Subject: " & iMessage.Subject & vbLf & _
"DateRecdeived: " & iMessage.ReceivedTime & vbLf & vbLf

Set iMessage = Nothing

Case "urn:content-classes:person"
Dim iPerson As New CDO.Person
iPerson.DataSource.Open strObjectUrl

' display some properties
Debug.Print "Person" & vbLf & _
"First Name: " & iPerson.FirstName & vbLf & _
"Last Name: " & iPerson.LastName & vbLf & _
"Title: " & iPerson.Title & vbLf & _
"Company: " & iPerson.Company & vbLf & vbLf

Set iPerson = Nothing

Case "urn:content-classes:appointment"
Dim iAppointment As New CDO.Appointment
iAppointment.DataSource.Open strObjectUrl

' display some properties
Debug.Print "Appointment" & vbLf & _
"Subject: " & iAppointment.Subject & vbLf & _
"Location: " & iAppointment.Location & vbLf & _
"StartTime: " & iAppointment.StartTime & vbLf & _
"EndTime: " & iAppointment.EndTime & vbLf & vbLf

Set iAppointment = Nothing

Case Else
Debug.Print "The case :" & strContentClass & " is not included here"
End Select

End If

Rst.MoveNext
Loop

' close connections
Rst.Close
Rec.Close

' clear up
Set Rst = Nothing
Set Rec = Nothing

If Err.Number = 0 Then
Debug.Print "Good Job!"
End If
End Sub

Private Function GetDomainDNSName() As String
Dim Info As New ADSystemInfo
Dim strDomain As String
strDomain = Info.DomainDNSName

GetDomainDNSName = strDomain
End Function

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Searching/Deleting Using ADO

Visual Basic

Note The following example uses a file URL with the Exchange OLE DB (ExOLEDB) provider. The ExOLEDB provider also supports the HTTP URL scheme. Using the HTTP URL scheme allows both client and server applications to use a single URL scheme.
'Searching/Deleting Items using ADO
'This sample shows how to use Recordset to delete object after search
'
'Make reference to the ADO 2.5 library
'Make reference to Active DS Type Library

Private Sub SeachDeleteItem()
Dim strDomainName As String
Dim strUser As String

Dim strLocalPathOfSourceFolder As String
Dim strSourceFolderUrl As String
Dim strSearchSql As String

' specify the domain and user
strDomainName = GetDomainDNSName()
strUser = "user1"

' Sample 1: Delete Appointments in 'Calendar' with subject = 'Test'
strPathOfSourceFolder = "MBX/" & strUser & "/Calendar"

strSourceFolderUrl = "file://./backofficestorage/" & _
strDomainName & "/" & strLocalPathOfSourceFolder

' create the SQL query for the recordset (appointments) to be deleted
strSearchSql = "select "
strSearchSql = strSearchSql & " ""urn:schemas:mailheader:content-class"""
strSearchSql = strSearchSql & ", ""DAV:href"""
strSearchSql = strSearchSql & ", ""DAV:displayname"""
strSearchSql = strSearchSql & ", ""DAV:isfolder"""
strSearchSql = strSearchSql & ", ""urn:schemas:httpmail:subject"""
strSearchSql = strSearchSql & " from scope ('shallow traversal of " & Chr(34)
strSearchSql = strSearchSql & strSourceFolderUrl & """') "
strSearchSql = strSearchSql & " WHERE ""DAV:ishidden"" = false"
strSearchSql = strSearchSql & " AND ""urn:schemas:httpmail:subject"" = 'Test'"
strSearchSql = strSearchSql & " AND ""DAV:isfolder"" = false"

'Call SearchDeleteObjects(strDomainName, strLocalPathOfSourceFolder, strSearchSql)

' Sample 2: Delelte the file Hello.txt from the following folder
strLocalPathOfSourceFolder = "MBX/" & strUser & "/Deleted Items"

strSourceFolderUrl = "file://./backofficestorage/" & _
strDomainName & "/" & strLocalPathOfSourceFolder

' create the SQL query for the recordset (Hello.txt) to be deleted
strSearchSql = "select "
strSearchSql = strSearchSql & " ""urn:schemas:mailheader:content-class"""
strSearchSql = strSearchSql & ", ""DAV:href"""
strSearchSql = strSearchSql & ", ""DAV:displayname"""
strSearchSql = strSearchSql & ", ""DAV:isfolder"""
strSearchSql = strSearchSql & " from scope ('shallow traversal of " & Chr(34)
strSearchSql = strSearchSql & strSourceFolderUrl & """') "
strSearchSql = strSearchSql & " WHERE ""DAV:ishidden"" = false"
strSearchSql = strSearchSql & " AND ""DAV:displayname"" = 'Hello.txt'"
strSearchSql = strSearchSql & " AND ""DAV:isfolder"" = false"

'Call SearchDeleteObjects(strDomainName, strLocalPathOfSourceFolder, strSearchSql)

' Sample 3: Delete subfolder "TestFolder" under "Public Folders"
'strLocalPathOfSourceFolder = "Public Folders"
strPathOfSourceFolder = "MBX/" & strUser & "/Deleted Items"

strSourceFolderUrl = "file://./backofficestorage/" & _
strDomainName & "/" & strLocalPathOfSourceFolder

' create the SQL query for the recordset (folder 'TestFolder') to be deleted
strSearchSql = "select "
strSearchSql = strSearchSql & " ""urn:schemas:mailheader:content-class"""
strSearchSql = strSearchSql & ", ""DAV:href"" "
strSearchSql = strSearchSql & ", ""DAV:displayname"""
strSearchSql = strSearchSql & ", ""DAV:isfolder"""
strSearchSql = strSearchSql & " from scope ('shallow traversal of " & Chr(34)
strSearchSql = strSearchSql & strSourceFolderUrl & """') "
strSearchSql = strSearchSql & " WHERE ""DAV:ishidden"" = false"
strSearchSql = strSearchSql & " AND ""DAV:isfolder"" = true"
strSearchSql = strSearchSql & " AND ""DAV:displayname"" = 'HelloFolder'"

Call SearchDeleteObjects(strDomainName, strLocalPathOfSourceFolder, strSearchSql)

Unload Me
End Sub

Private Sub SearchDeleteObjects(strDomainName As String, strPathOfSourceFolder As String, strRestricSql As String)
Dim Rec As New ADODB.Record
Dim Rst As New ADODB.Recordset
Dim strSourceFolderUrl As String

' set the URL to the location of the folder under which the objects are searched
strSourceFolderUrl = "file://./backofficestorage/" & _
strDomainName & "/" & strPathOfSourceFolder

' open the record
Rec.Open strSourceFolderUrl, , adModeReadWrite 'delete needs parameter adModeReadWrite

' open the recordset - a list of items
Rst.Open strRestricSql, Rec.ActiveConnection

Rst.MoveFirst
Do While Not Rst.EOF

Dim strItemUrl As String
Dim strContentClass As String

' retrieve some propertied
strItemUrl = Rst.Fields("DAV:href")
strContentClass = Rst.Fields("urn:schemas:mailheader:content-class")

'MsgBox Rst.Fields("DAV:displayname")

Rst.Delete 1

' here may make further restriction to the objects to be deleted.
' For example if searched under the Calendar folder
' dim strSubject as string
' dim strLocation as string
' strSubject = Rst.Fields("urn:schemas:httpmail:subject")
' strLocation = Rst.Fields("urn:schemas:calendar:location")
' if strSubject = "Hello" AND strLocation = "LPB-C" then
' Rst.Delete
' End If

Rst.MoveNext
Loop

' close connections
Rst.Close
Rec.Close

' clear up
Set Rst = Nothing
Set Rec = Nothing

If Err.Number = 0 Then
MsgBox "Good Job!"
End If

End Sub

Private Function GetDomainDNSName() As String
Dim Info As New ADSystemInfo
Dim strDomain As String
strDomain = Info.DomainDNSName

GetDomainDNSName = strDomain
End Function

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Modifying Objects Using CDOEX and ADO

Visual Basic

Note The following example uses a file URL with the Exchange OLE DB (ExOLEDB) provider. The ExOLEDB provider also supports the HTTP URL scheme. Using the HTTP URL scheme allows both client and server applications to use a single URL scheme.
'Modify Object using CDOEx and ADO
' This sample shows how to do the following after search
' - Change folder name
' - Modify appointments
' - Modify contacts
'
' Make reference to  CDO for Exchange 2000 and ADO 2.5 libraries
' Make reference to Active DS Typy Library

     Private Sub ModifyObject()
Dim strDomainName As String
Dim strUser As String

Dim strLocalPathOfSourceFolder As String
Dim strSourceFolderUrl As String
Dim strSearchSql As String

' specify the domain and user
strDomainName = GetDomainDNSName()
strUser = "user1"

' Sample 1: Modify Appointments in 'Calendar'
strLocalPathOfSourceFolder = "MBX/" & strUser & "/Calendar"

strSourceFolderUrl = "file://./backofficestorage/" & _
strDomainName & "/" & strLocalPathOfSourceFolder

' create the SQL query for the recordset (appointments)
strSearchSql = "select "
strSearchSql = strSearchSql & " ""urn:schemas:mailheader:content-class"""
strSearchSql = strSearchSql & ", ""DAV:href"""
strSearchSql = strSearchSql & ", ""DAV:displayname"""
strSearchSql = strSearchSql & ", ""DAV:isfolder"""
strSearchSql = strSearchSql & ", ""DAV:iscollection"""
strSearchSql = strSearchSql & ", ""urn:schemas:calendar:title"""
strSearchSql = strSearchSql & " from scope ('shallow traversal of " & Chr(34)
strSearchSql = strSearchSql & strSourceFolderUrl & """') "
strSearchSql = strSearchSql & " WHERE ""DAV:ishidden"" = false"
strSearchSql = strSearchSql & " AND ""DAV:isfolder"" = false"

Call ModifyObjects(strDomainName, _
strLocalPathOfSourceFolder, _
strSearchSql)

' Sample 2: Modify Contacts in 'Ccontacts'
strLocalPathOfSourceFolder = "MBX/" & strUser & "/Contacts"

strSourceFolderUrl = "file://./backofficestorage/" & _
strDomainName & "/" & strLocalPathOfSourceFolder

' create the SQL query for the recordset (appointments)
strSearchSql = "select "
strSearchSql = strSearchSql & " ""urn:schemas:mailheader:content-class"""
strSearchSql = strSearchSql & ", ""DAV:href"""
strSearchSql = strSearchSql & ", ""DAV:displayname"""
strSearchSql = strSearchSql & ", ""urn:schemas:Contacts:Title""" '
strSearchSql = strSearchSql & ", ""DAV:isfolder"""
strSearchSql = strSearchSql & ", ""DAV:iscollection"""
strSearchSql = strSearchSql & ", ""urn:schemas:calendar:title"""
strSearchSql = strSearchSql & " from scope ('shallow traversal of " & Chr(34)
strSearchSql = strSearchSql & strSourceFolderUrl & """') "
strSearchSql = strSearchSql & " WHERE ""DAV:ishidden"" = false"
strSearchSql = strSearchSql & " AND ""DAV:isfolder"" = false"

Call ModifyObjects(strDomainName, _
strLocalPathOfSourceFolder, _
strSearchSql)

' Sample 3: Change for tje folder named "TestFolder" of the subfolder of 'MBX/Outbox' to "MidifiedFolder"
strLocalPathOfSourceFolder = "MBX/" & strUser & "/Outbox"

strSourceFolderUrl = "file://./backofficestorage/" & _
strDomainName & "/" & strLocalPathOfSourceFolder

' create the SQL query for the recordset (appointments)
strSearchSql = "select "
strSearchSql = strSearchSql & " ""urn:schemas:mailheader:content-class"""
strSearchSql = strSearchSql & ", ""DAV:href"""
strSearchSql = strSearchSql & ", ""DAV:displayname"""
strSearchSql = strSearchSql & ", ""DAV:isfolder"""
strSearchSql = strSearchSql & ", ""DAV:iscollection"""
strSearchSql = strSearchSql & " from scope ('shallow traversal of " & Chr(34)
strSearchSql = strSearchSql & strSourceFolderUrl & """') "
strSearchSql = strSearchSql & " WHERE ""DAV:ishidden"" = false"
strSearchSql = strSearchSql & " AND ""DAV:isfolder"" = true"
strSearchSql = strSearchSql & " AND ""DAV:iscollection"" = true"
strSearchSql = strSearchSql & " AND ""DAV:displayname"" = 'TestFolder'"

Call ModifyObjects(strDomainName, _
strLocalPathOfSourceFolder, _
strSearchSql)

Unload Me
End Sub

Private Sub ModifyObjects(strDomainName As String, _
strLocalPathOfSourceFolder As String, _
strRestrictSql As String)

Dim Rec As New ADODB.Record
Dim Rst As New ADODB.Recordset
Dim strSourceFolderUrl As String

' set the strURL to the location of the folders
strSourceFolderUrl = "file://./backofficestorage/" & _
strDomainName & "/" & strLocalPathOfSourceFolder

' open record
Rec.Open strSourceFolderUrl, , adModeReadWrite 'Modify needs parameter adModeReadWrite

If Rec.State = adStateOpen Then
Debug.Print "Rec opened"
End If

' open recordset, a list of objects
Rst.Open strRestrictSql, Rec.ActiveConnection ', adOpenForwardOnly, adLockOptimistic

If Rst.RecordCount = 0 Then
Debug.Print "No searched objects found!"
Exit Sub
End If

' now found some objects
Rst.MoveFirst
Do While Not Rst.EOF

Dim strObjectUrl As String
Dim strContentClass As String

' retrieve some properties
strObjectUrl = Rst.Fields("DAV:href")
strContentClass = Rst.Fields("urn:schemas:mailheader:content-class")

If Rst.Fields("DAV:iscollection") = True Then
Debug.Print "FolderName : " & Rst.Fields("DAV:displayname") & vbLf & vbLf

' change folder name using 'Move' from Record
Dim tempRec As New ADODB.Record
Dim strFolderName As String ' new folder name
strFolderName = "NameChangedFolder" ' New folder name

' open the record
tempRec.Open strObjectUrl, , adModeReadWrite 'Modify needs parameter adModeReadWrite
tempRec.MoveRecord strObjectUrl, strSourceFolderUrl & "/" & strFolderName

' close the temp reccord
tempRec.Close

Else
Select Case strContentClass
Case "urn:content-classes:message"
Dim iMessage As New CDO.Message
iMessage.DataSource.Open strObjectUrl, Rec.ActiveConnection, adModeReadWrite

Debug.Print "Message" & vbLf & _
"Sender: " & iMessage.Sender & vbLf & _
"Subject: " & iMessage.Subject & vbLf & _
"DateRecdeived: " & iMessage.ReceivedTime & vbLf & vbLf

Set iMessage = Nothing

Case "urn:content-classes:person"
Dim iPerson As New CDO.Person
iPerson.DataSource.Open strObjectUrl, Rec.ActiveConnection, adModeReadWrite

Debug.Print "Person" & vbLf & _
"First Name: " & iPerson.FirstName & vbLf & _
"Last Name: " & iPerson.LastName & vbLf & _
"Title: " & iPerson.Title & vbLf & _
"Company: " & iPerson.Company & vbLf & vbLf

'Modify property directly
iPerson.Title = "Support Engineer"
iPerson.DataSource.Save

'Modify property using Fields
iPerson.Fields("urn:schemas:contacts:title") = "Manager"
iPerson.Fields.Update
iPerson.DataSource.Save

Set iPerson = Nothing

Case "urn:content-classes:appointment"
Dim iAppointment As New CDO.Appointment
iAppointment.DataSource.Open strObjectUrl, Rec.ActiveConnection, adModeReadWrite

Debug.Print "Appointment" & vbLf & _
"Subject: " & iAppointment.Subject & vbLf & _
"Location: " & iAppointment.Location & vbLf & _
"StartTime: " & iAppointment.StartTime & vbLf & _
"EndTime: " & iAppointment.EndTime & vbLf & vbLf

' Modify some properties directly
iAppointment.Subject = "Subject changed"

' modify property using Fields
iAppointment.Fields("urn:schemas:calendar:location") = "Issaqua"
iAppointment.Fields.Update
iAppointment.DataSource.Save

Set iAppointment = Nothing

Case Else
Debug.Print "The case :" & strContentClass & " is not included here"
End Select

End If

Rst.MoveNext
Loop

' close connections
Rst.Close
Rec.Close

' clear up
Set Rst = Nothing
Set Rec = Nothing

If Err.Number = 0 Then
Debug.Print "Good Job!"
End If

End Sub

Private Function GetDomainDNSName() As String
Dim Info As New ADSystemInfo
Dim strDomain As String
strDomain = Info.DomainDNSName

GetDomainDNSName = strDomain
End Function

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Creating Search Folders

To create a search folder using the WebDAV protocol, perform the following steps:

  1. Create an MKCOL WebDAV request. The request Uniform Resource Identifier (URI) should be the location of the new search folder, for example, http://myserver/pub2/folders/search_folder.
  2. In the body of the request, send a DAV:propertyupdate XML stream. Specify the Structured Query Language (SQL) statement in the DAV:sql portion of the DAV:searchrequest property.
  3. Send the request to the HTTP service on the machine that hosts the Web Storage System in which the new search folder is to be created.
  4. If successful, the HTTP service will respond with the status 207 Multi-Status, the new folder creation will have the status 201 Created, and the property update will have the status 200 OK.
Note Search folders cannot be created in the one public folder tree (and associated public information store) designated for MAPI clients. If you attempt to create a search folder in this public folder tree, the Web server will return an error. This public folder tree is, by default, made available through the '/public' HTTP virtual root.

The following example shows what the request body might look like:

MKCOL /pub2/search_folder/ HTTP/1.1
Host: somedomain.microsoft.com
Content-Length: XXX
Content-type: text/xml

<?xml version="1.0"?>
<a:propertyupdate xmlns:a="DAV:" >
    <a:set>
        <a:prop>
            <a:searchrequest>
                <a:sql>
                     Select "DAV:displayname"
                     FROM Scope('shallow traversal of "/pub2/folder1 "')
                     WHERE ""DAV:ishidden"" = false AND
                           ""DAV:isfolder"" = false
                </a:sql>
            </a:searchrequest>
        </a:prop>
    </a:set>
</a:propertyupdate>

In addition, a successful response might be:

HTTP/1.1 207 Multi-Status
Server: Microsoft-IIS/5.0
Date: Tue, 22 Feb 1999 12:54:46 GMT
WWW-Authenticate: Negotiate AADAB...
MS-Exchange-Permanent-URL: http://hostname/pub2/-FlatUrlSpace-/ab7e2af09631
b745981c6d39445456f2-17/
Location: http://hostname/pub2/search_folder/
Timeout: Infinity
Repl-UID: <rid:ab7e2af09631b745981c6d39445456f2000000001371>
Content-Type: text/xml
Content-Length: XXX
ResourceTag: <rt:ab7e2af09631b745981c6d39445456f2000000001371ab7e2af09631b745981
c6d39445456f2000000001573>

<?xml version="1.0"?>
<a:multistatus xmlns:a="DAV:">
  <a:response>
    <a:href>http://hostname/pub2/search_folder</a:href>
    <a:status>HTTP/1.1 201 Created</a:status>
    <a:propstat>
       <a:status>HTTP/1.1 200 OK</a:status>
       <a:prop><a:searchrequest/></a:prop>
    </a:propstat>
  </a:response>
</a:multistatus>
Note To reiterate: you can create search folders in all mailbox stores and all public folder trees except the public folder tree designated for MAPI clients. This public folder tree is be default made available through the '/public' virtual root.

The following example uses an instance of the Microsoft.XMLHTTP Component Object Model (COM) class to create and send the request to the server. It then returns a reference to the object. The XML stream for the request body is hard-coded by using a string variable. You can also use an instance of the Microsoft.XMLDOM COM class to create the XML stream for the request body.

JScript

function createSearchFolder( folderURL, SQL ) {
  var Req;
  Req = new ActiveXObject("Microsoft.XMLHTTP");

  Req.Open("MKCOL", folderURL, false);
  strR = "<?xml version='1.0'?>";
  strR += "<d:propertyupdate xmlns:d='DAV:'>";
  strR += "<d:set><d:prop><d:searchrequest><d:sql>" + SQL + "</d:sql>";
  strR += "</d:searchrequest></d:prop></d:set></d:propertyupdate>";
  Req.SetRequestHeader("Content-type:", "text/xml");

  Req.send(strR);

  if(! Req.Status == "207") { // Multi-Status response
    // handle error
  }

  return Req;
}

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Web Storage System Search Folders

You can create collections of items that are the results of a Structured Query Language (SQL) search directly in the Web Storage System within a search folder when using the WebDAV protocol. Like other folders in the Web Storage System, persisted search folders are addressable using a URL and can be accessed and queried.

Using search folders in the Web Storage System frees you from having to write your own code to save SQL search results for subsequent use by your clients. You can create search folders in private stores and public folders, except for the public folder tree designated for MAPI clients. Search folders can be created only using the WebDAV protocol. See WebDAV Search Folder Creation Protocol Command.

The items stored in a search folder are those items that exist within the folder scope and match the conditions you specify with an SQL SELECT statement when you create the search folder. That is, the folder does not contain copies of the items, but rather links to the items themselves. This is made possible through the Web Storage System's single-instancing technology.

Although search folders are based on an SQL SELECT statement, they provide a mechanism far more powerful than simply storing the results returned by a standard SQL SELECT command. Using persisted search folders, you can arbitrarily group items within a particular folder scope that match the criteria you specify and then place them in another folder for subsequent searching or monitoring by your application.

For example, one part of your application may need to routinely return various property values for all items belonging to the hypothetical content class urn:schemas-myorganization-tld:statusreport that exists within your application's folder hierarchy, which could be many levels deep. Rather than continuously executing a deep traversal search for the property values on items belonging to this content class, you could instead create a search folder for the application's folder hierarchy with the condition that each matched item in the folder belongs to the specified content class urn:schemas-myorganization-tld:statusreport. After the search folder is constructed, you could then routinely query it to retrieve property values for these items only. Because the Web Storage SystemSQL engine need not re-traverse the entire folder scope and re-filter these items, search performance is greatly improved.

The Web Storage System constructs search folders asynchronously with respect to client requests. That is, when a successful creation request is made and the client receives this response from the service, not all items that match the SQL request have yet been linked to the search folder.

Related Topics

  • Search Folder Properties
  • Search Folder Items
  • WebDAV Search Folder Creation Protocol Command

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Search Folder Properties

Search folders are like normal folders: Once created, they contain standard properties defined for folders, and they can be searched for items and then deleted when no longer needed. However, the Web Storage System sets special properties on persisted search folders. The following table lists these properties and their descriptions.

Property | Description
DAV:searchtype | The Web Storage System sets this property to "dynamic".
DAV:searchrequest (Read-Only) | The Web Storage System places the Structured Query Language (SQL) query statement used to populate the search folder in this property.
DAV:resourcetype | The Web Storage System sets this property to the value "DAV:collection/DAV:searchresults/" for search folders.

Related Topics

  • Search Folder Items
  • WebDAV Search Folder Creation Protocol Command

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Search Folder Items

When you create a search folder, you specify a Structured Query Language (SQL) command that the Web Storage System uses to populate the folder with items. After the folder has been populated, links to all items that match your request are placed in the folder. Additionally, each item's complete set of properties is also available. Because of this, the list of properties you specify when creating the search folder does not limit which properties you can access or search for within the search folder itself. You can issue PROPGET and SEARCH commands for items in the folder in the normal way. The most important aspect of the SQL command used to construct the folder is the WHERE clause condition.

If you issue a SELECT * search command or an WebDAV PROPFIND command (depth 1) with a scope that contains the search folder, you receive the properties defined by the original containing folder's schema. That is, the list of properties returned by the SELECT * command for a search folder is not controlled by the search folder's schema, but rather by the item's containing folder itself. This also holds true when you issue a PROPGET command. In summary, the normal schema rules for items in a folder still apply as if the items were being accessed in their actual containing folder.

You cannot add new items to a search folder manually. If you issue a PUT, POST, or normal MKCOL command for an item in the search folder, the Web Storage System returns an error. You can, however, nest-search folders.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


WebDAV Search Folder Creation Protocol Command

You create a search folder just as you would create a standard folder using the WebDAV MKCOL command. However, along with the MKCOL request, you specify an XML request body containing a value for the folder's DAV:searchrequest property. The value of this property is set to an Structured Query Language (SQL) query used to construct the contents of the persisted search folder. Note that when setting a value for the DAV:searchrequest property, you specify the SQL statement within a DAV: sql subelement, as in the following example:

<a:searchrequest xmlns:a="DAV:">
  <a:sql>select * from scope(...)</a:sql>
</a:searchrequest>

The following is an example of a persisted search folder WebDAV request. The XML portion has been formatted with extra spaces to aid readability and need not be formatted this way in your applications.

MKCOL /folderpath/search_folder/ HTTP/1.1
Host: somedomain.microsoft.com
Content-Length: XXX
Content-type: text/xml

<?xml version="1.0"?>
<a:propertyupdate xmlns:a="DAV:" >
    <a:set>
        <a:prop>
           <a:searchrequest>
              <a:sql>
                   Select "DAV:displayname"
                   FROM Scope('shallow traversal of
                        "/exchange/user1/inbox"')
                 </a:sql>
            </a:searchrequest>
        </a:prop>
    </a:set>
</a:propertyupdate>

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Example Search Folder HTTP Request and Response

The following is a sample client/server dialog. The client requests the creation of a search folder at the URL "http://somedomain.microsoft.com/public2/ps1/" that contains the items that satisfy the following Structured Query Language (SQL) search command:

SELECT *
FROM scope('shallow traversal of
   "http:// somedomain.microsoft.com/public2/templates/"')
WHERE "DAV:ishidden"     = False
AND   "DAV:contentclass" = "urn:schemas-mydomain-tld:reporttemplate"

Client Request

The client connects to port 80 ( HTTP) on the host with Domain Name System (DNS) name somedomain.microsoft.com and sends the command in the following example to the server. (Note that, for purposes of brevity and clarity, some standard headers that are usually sent with these requests (such as Accept-Language:) have been omitted from this example.)

MKCOL /pub2/templates/search_folder/ HTTP/1.1
Host: somedomain.microsoft.com
Content-Length: XXX
Content-type: text/xml

<?xml version="1.0"?>
<a:propertyupdate xmlns:a="DAV:">
  <a:set>
    <a:prop>
      <a:searchrequest>
        <a:sql>
       SELECT *
       FROM scope('shallow traversal of
         "http://somedomain.microsoft.com/pub2/templates"')
       WHERE "DAV:ishidden" = False
       AND "DAV:contentclass" = "urn:schemas-mydomain-tld:reporttemplate"
        </a:sql>
      </a:searchrequest>
    </a:prop>
  </a:set>
</a:propertyupdate>

Server Response

The server then sends the following response to the client:

HTTP/1.1 207 Multi-Status
Server: Microsoft-IIS/5.0
Date: Tue, 22 Feb 1999 12:54:46 GMT
WWW-Authenticate: Negotiate AADAB...
MS-Exchange-Permanent-URL:
     http://hostname/pub2/-FlatUrlSpace-/ab7e2af09631
b745981c6d39445456f2-17/
Location: http://hostname/pub2/templates/search_folder/
Timeout: Infinity
Repl-UID: <rid:ab7e2af09631b745981c6d39445456f2000000001371>
Content-Type: text/xml
Content-Length: XXX
ResourceTag: <rt:ab7e2af09631b745981c6d39445456f200000000
1371ab7e2af09631b745981
c6d39445456f2000000001573>

<?xml version="1.0"?>
<a:multistatus xmlns:a="DAV:">
  <a:response>
    <a:href>
     http://hostname/pub2/templates/search_folder
    </a:href>
    <a:status>HTTP/1.1 201 Created</a:status>
    <a:propstat>
       <a:status>HTTP/1.1 200 OK</a:status>
       <a:prop><a:searchrequest/></a:prop>
    </a:propstat>
  </a:response>
</a:multistatus>

After this successful response has been sent, the Web Storage System begins populating the search folder with the items that satisfy the SQL request. Be aware that not all items that match the criteria appear in the search folder until the Web Storage System completes the construction of the folder.

Note The server has sent a different Timeout value for the search. The Location header returned can be different from the value sent by the client when the MKCOL request was made.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Using Schema

The creation of schemas for your application can be broken down into the following two steps:

  1. Create schema definition items for your application.

    Schema definition items are items that define properties and content classes for your application. These items can be in any folder in the private store or public information store in which your application runs. Normally, you designate one or more folders to contain your application's schema definition items, and you add each folder to your application folder's schema scope.

  2. Configure the schema scope of your application folders.

    After you have created your schema definition items and placed them in a folder in the public information store or private store where your application runs, you need to configure the scope of your application and schema folders. In doing so, you make your schema definition items visible to your application and to others that rely on a folder's schema scope, such as the Web Storage System Structured Query Language (SQL) query processor for SELECT * requests.

The following sections describe how to perform those steps:

Creating Property Definitions

Creating Content Class Definitions

Specifying Expected Content Classes for Folders

Configuring a Folder's Schema Scope

Testing Your Schema

Importing Schema

Using Folder Content-Class

The location of the folder(s) that contains your schema definition items is up to you.

Related Topics

  • Web Storage System Schema

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Creating Property Definitions

To create a property definition, perform the following steps:

  1. Create an item in one of your application's schema folders. You must place the item in a folder that is in your application folder's schema scope.
  2. Set the item's DAV:contentclass to the value "urn:content-classes:propertydef". This identifies the item as a property definition.
  3. Set the name of the property by using the urn:schemas-microsoft-com:xml-data#name property for the item. This name is used to refer to the property definition. Note that this name is not the URL for the item. For example, a property definition located at the URL http://server/public/myapplication/schema/property1 may have the name "urn:schemas-myschema-tld:propA". This name is used to refer to the property in applicable item fields, such as the urn:schemas-microsoft-com:xml-data#element property for a content class definition item.
  4. Set the property's data type by using the urn:schemas-microsoft-com:datatypes#type field.
  5. Define whether the property is multivalued by setting the urn:schemas-microsoft-com:exch-data:ismultivalued property for the item.

VBScript

<job id="createpropdefs">
<reference object="adodb.record"/>
<script language="vbscript">

Dim InfoNT
Set InfoNT = CreateObject("WinNTSystemInfo")
Dim sPath
sPath = "/public/test_folder/schema/"

CreatePropDefs "http://" & InfoNT.ComputerName & sPath

Sub CreatePropDefs( sSchemaFolderUrl )

 '
 ' This example creates the following property definitions:
 '   urn:schemas-domain-tld:submitdate
 '   urn:schemas-domain-tld:cuisine
 '   urn:schemas-domain-tld:title
 '   urn:schemas-domain-tld:ingredients
 '   urn:schemas-domain-tld:instructions
 '   urn:schemas-domain-tld:rating
 ' These properties are used in the urn:schemas-domain-tld:content-classes:recipe
 ' content class.
 '
 ' A URN scheme is used for the namespace: "urn:schemas-domain-tld:"
 '  where "tld" refers to "top-level domain".

 Dim Conn
 set Conn = CreateObject("ADODB.Connection")
 conn.Provider = "ExOLEDB.DataSource"
 Conn.Open sSchemaFolderUrl

 Dim Rec
 Set Rec = CreateObject("ADODB.Record")

 ' Create the property definition in the schema folder for submitdate
 Rec.Open sSchemaFolderUrl & "submitdate", Conn, adModeReadWrite, adCreateNonCollection
 Set Flds = Rec.Fields
 With Flds
   .Item("DAV:contentclass") = "urn:content-classes:propertydef"
   .Item("urn:schemas-microsoft-com:xml-data#name")  = "urn:schemas-domain-tld:submitdate"
   .Item("urn:schemas-microsoft-com:datatypes#type") = "dateTime"
   .Item("urn:schemas-microsoft-com:exch-data:ismultivalued") = False
   .Item("urn:schemas-microsoft-com:exch-data:isindexed")     = True
   .Item("urn:schemas-microsoft-com:exch-data:isreadonly")    = False
   .Update
 End With
 Rec.Close

 ' Create the property definition in the schema folder for cuisine
 Rec.Open sSchemaFolderUrl & "cuisine", Conn, adModeReadWrite, adCreateNonCollection
 Set Flds = Rec.Fields
 With Flds
   .Item("DAV:contentclass") = "urn:content-classes:propertydef"
   .Item("urn:schemas-microsoft-com:xml-data#name")  = "urn:schemas-domain-tld:cuisine"
   .Item("urn:schemas-microsoft-com:datatypes#type") = "string"
   .Item("urn:schemas-microsoft-com:exch-data:ismultivalued") = False
   .Item("urn:schemas-microsoft-com:exch-data:isindexed")     = False
   .Item("urn:schemas-microsoft-com:exch-data:isreadonly")    = False
   .Update
 End With
 Rec.Close

 ' Create the property definition in the schema folder for title
 Rec.Open sSchemaFolderUrl & "title", Conn, adModeReadWrite, adCreateNonCollection
 Set Flds = Rec.Fields
 With Flds
   .Item("DAV:contentclass") = "urn:content-classes:propertydef"
   .Item("urn:schemas-microsoft-com:xml-data#name")  = "urn:schemas-domain-tld:title"
   .Item("urn:schemas-microsoft-com:datatypes#type") = "string"
   .Item("urn:schemas-microsoft-com:exch-data:ismultivalued") = False
   .Item("urn:schemas-microsoft-com:exch-data:isindexed")     = True
   .Item("urn:schemas-microsoft-com:exch-data:isreadonly")    = False
   .Update
 End With
 Rec.Close

 ' Create the property definition in the schema folder for ingredients
 Rec.Open sSchemaFolderUrl & "ingredients", Conn,adModeReadWrite, adCreateNonCollection
 Set Flds = Rec.Fields
 With Flds
   .Item("DAV:contentclass") = "urn:content-classes:propertydef"
   .Item("urn:schemas-microsoft-com:xml-data#name")  = "urn:schemas-domain-tld:ingredients"
   .Item("urn:schemas-microsoft-com:datatypes#type") = "string"

   ' Note that ismultivalued is set to true for handling multiple ingredients
   .Item("urn:schemas-microsoft-com:exch-data:ismultivalued") = True
   .Item("urn:schemas-microsoft-com:exch-data:isindexed")     = True
   .Item("urn:schemas-microsoft-com:exch-data:isreadonly")    = False
   .Update
 End With
 Rec.Close

 ' Create the property definition in the schema folder for instructions
 Rec.Open sSchemaFolderUrl & "instructions", Conn,adModeReadWrite, adCreateNonCollection
 Set Flds = Rec.Fields
 With Flds
   .Item("DAV:contentclass") = "urn:content-classes:propertydef"
   .Item("urn:schemas-microsoft-com:xml-data#name")  = "urn:schemas-domain-tld:instructions"
   .Item("urn:schemas-microsoft-com:datatypes#type") = "string"

   ' Note that ismultivalued is set to true for handling multiple instructions
   .Item("urn:schemas-microsoft-com:exch-data:ismultivalued") = True
   .Item("urn:schemas-microsoft-com:exch-data:isindexed")     = False
   .Item("urn:schemas-microsoft-com:exch-data:isreadonly")    = False
   .Update
 End With
 Rec.Close

 ' Create the property definition in the schema folder for rating
 Rec.Open sSchemaFolderUrl & "rating", Conn, adModeReadWrite, adCreateNonCollection
 Set Flds = Rec.Fields
 With Flds
   .Item("DAV:contentclass") = "urn:content-classes:propertydef"
   .Item("urn:schemas-microsoft-com:xml-data#name")  = "urn:schemas-domain-tld:rating"
   .Item("urn:schemas-microsoft-com:datatypes#type") = "int"
   .Item("urn:schemas-microsoft-com:exch-data:ismultivalued") = False
   .Item("urn:schemas-microsoft-com:exch-data:isindexed")     = True
   .Item("urn:schemas-microsoft-com:exch-data:isreadonly")    = False
   .Update
 End With
 Rec.Close

End Sub
</script>
</job>

Related Topics

  • Creating Content Class Definitions
  • Configuring a Folder's Schema Scope
  • Web Storage System Schema

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Creating Content Class Definitions

To create a content-class definition item, follow these steps:

  1. Create a non-folder item to hold the content class definition. You must place the item in a folder that is in your application folder's schema scope.
  2. Set the item's DAV:contentclass field to the value urn:content-classes:contentclassdef. This identifies the item as a content class definition.
  3. Set the content class's name using the urn:schemas-microsoft-com:xml-data#name property for the item. This name refers to the content class definition. Note that this name is not the URL for the item. For example, a content class definition located at the URL http://server/public/myapplication/schema/contentclass1 could have the name "urn:schemas-myschema-tld:content-classes:class1". This name refers to the content class in applicable item fields, for example, a folder's expected-content-class or an item's DAV:contentclass property.
  4. Optionally, you can extend other content classes by setting the urn:schemas-microsoft-com:xml-data#extends property for the item. This property is an array of strings, in which each string is the name of a content class as designated by the class's urn:schemas-microsoft-com:xml-data#name field. When you extend other content class definition items, your class inherits the property definitions set for each of these classes.
  5. You can also specify the names of property definitions to associate with the content class. If this class extends others, you do not need to specify property names for those classes; they are inherited. To specify the names of property definitions, you set the urn:schemas-microsoft-com:xml-data#element property for the item. This property is an array of strings, in which each string is the name of a property definition in the schema scope.

VBScript

<Job id="CreateCCDef">
<reference object="adodb.record"/>
<script language="vbscript">

Dim Conn
Dim Info
Dim InfoNT
Dim sSchemaFolderURL

Set Info   = CreateObject("ADSystemInfo")
Set InfoNT = CreateObject("WinNTSystemInfo")

sVrootURL        = "http://" & InfoNT.ComputerName & "." & Info.DomainDNSName & "/public"
sSchemaFolderURL = sVrootURL & "/test_folder/schema"

Set Conn = CreateObject("ADODB.Connection")
Conn.Provider = "ExOLEDB.DataSource"
Conn.Open sVrootURL

CreateCCDef sSChemaFolderURL, Conn

Sub CreateCCDef( sSchemaFolderURL, Conn )

  Const adModeReadWrite       = 3
  Const adFailIfNotExists     = -1
  Const adCreateNonCollection = 0

  Dim Rec
  Set Rec = CreateObject("ADODB.Record")

  Rec.Open sSchemaFolderURL & "/ccdef-recipe", Conn, adModeReadWrite, adCreateNonCollection

  Dim Flds
  Set Flds = Rec.Fields

  With Flds

    ' Name the content class.
    .Item("urn:schemas-microsoft-com:xml-data#name").Value = _
     "urn:schemas-domain-tld:content-classes:recipe"

    ' The content class of the definition item.
    .Item("DAV:contentclass") = "urn:content-classes:contentclassdef"

    ' The content classes it extends (inherits from).
    .Item("urn:schemas-microsoft-com:xml-data#extends").Value = _
        Array("urn:content-classes:item", "urn:content-classes:person")

    ' The properties to belong to this content class.
    .Item("urn:schemas-microsoft-com:xml-data#element").Value = _
         Array("urn:schemas-domain-tld:submitdate",_
               "urn:schemas-domain-tld:cuisine", _
               "urn:schemas-domain-tld:title", _
               "urn:schemas-domain-tld:ingredients", _
               "urn:schemas-domain-tld:instructions", _
               "urn:schemas-domain-tld:rating")

    .Update
  End With

  Rec.Close

End Sub
</script>
</Job>

Related Topics

  • Creating Property Definitions
  • Configuring a Folder's Schema Scope
  • Web Storage System Schema

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Specifying Expected Content Classes for Folders

Each folder item has a list of content class names in its urn:schemas-microsoft-com:exch-data:expected-content-class property. These names refer to the names of content class definition items that reside in the folder's schema scope. When you set this property for folders, you are indicating to schema-aware applications the list of content class names to expect items within the folder to be instances of. For example, the Web Storage System Structured Query Language (SQL) query processor uses this list of names, along with definition items in the folder's schema scope, to determine which properties it should return when a client issues a SELECT * command.

The list of content class names identified in this property does not restrict the possible values that you can set for an item's DAV:contentclass property. It merely acts as an indicator to schema-aware applications what class of content to expect in the folder.

The following example demonstrates how to set the urn:schemas-microsoft-com:exch-data:expected-content-class property on a folder.

VBScript

Note The following example uses a file URL with the Exchange OLE DB (ExOLEDB) provider. The ExOLEDB provider also supports the HTTP URL scheme. Using the HTTP URL scheme allows both client and server applications to use a single URL scheme.
' Update the application folder to specify the schema scope

Const adModeReadWrite   = 3
Const adFailIfNotExists = -1

Dim sURL
sURL = "file://./backofficestorage/microsoft.com/pubtreeroot"

Dim Rec
Dim Conn
Dim Flds

Set Conn = CreateObject("ADODB.Connection")
Set Rec  = CreateObject("ADODB.Record")

Conn.Provider = "ExOLEDB.DataSource"
Conn.Open sURL
Rec.Open  sURL & "/myapp/myappfolder/", Conn, adModeReadWrite

Set Flds = Rec.Fields
With Flds

  ' Specify which content classes are expected for this folder.
  ' Here, a custom content class is specified along with the standard folder
  ' content class urn:content-classes:folder.

   .Item("urn:schemas-microsoft-com:exch-data:expected-content-class").Value = _
       Array("urn:schemas-domain-tld:content-classes:mycontentclass", "urn:content-classes:folder")
   .Update
End With

Rec.Close

Related Topics

  • Web Storage System Schema
  • Schema Scope
  • Configuring a Folder's Schema Scope

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Configuring a Folder's Schema Scope

A schema scope is defined as the set of folders, identified by Uniform Resource Identifier (URI), that are traversed when searching for schema definition items. You need to define your application folder's schema scope so that your schema definition items are in the schema scope. You configure a folder's schema scope by using two folder properties:

  • urn:schemas-microsoft-com:exch-data:schema-collection-ref. This single-valued property, which can be set on any folder, specifies the URL that points to the first folder that contains applicable schema definition items. If this property is empty, the default location is the non_ipm_subtree/Schema folder of the public information store or private store. When you want to create your own schema definition items and apply them to items in your application folders, you set this property on each of your application folders.

    The schema scope for any folder always starts with a single folder in the store. You can further expand the scope by setting the urn:schemas-microsoft-com:exch-data:baseschema field on the first and subsequent schema folders. Normally, applications terminate the schema scope with the non_ipm_subtree/Schema folder, which contains the global Web Storage System schema definition items.

  • urn:schemas-microsoft-com:exch-data:baseschema. This multivalued field, which can be set on any folder, specifies the URLs for folders that contain additional, or base, schema definition items. When an application constructs the list of folders that are in a particular folder's schema scope, each folder identified by this property is added to the list in the order in which it appears in this field. Note that, by convention, you set this field for designated application schema folders and not for the application folder itself.

    The order in which folders are searched is significant: if two or more definition items exist that have the same name set in the definition item's urn:schemas-microsoft-com:xml-data#name property, only the first definition is used. See Schema Scope for more information about schema scope.

The following sections demonstrate how to set and examine these properties on folders in an application folder's schema scope.

Setting the Schema Collection Reference for a Folder

Setting the Base Schema Path for a Schema Folder

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Setting the Schema Collection Reference for a Folder

The following example demonstrates how to set the urn:schemas-microsoft-com:schema-collection-ref property for a folder. This property indicates the Uniform Resource Identifier (URI) of the first folder in which to search for schema definition items. If this property is not set, the default location is the non_ipm_subtree/Schema folder in the public information store or private store where the folder resides.

VBScript

<Job id="SetupFolderschema">
<reference object="adodb.record"/>

<script language="vbscript">

 Option Explicit

 Dim Info
 Dim InfoNT
 Dim oRec
 Dim oRec2
 Dim Conn
 Dim sVrootURL
 Dim sFolderURL
 Dim sSchemaFolderURL

 Set Info   = CreateObject("ADSystemInfo")
 Set InfoNT = CreateObject("WinNTSystemInfo")
 Set Conn   = CreateObject("ADODB.Connection")

 sVrootURL = "http://" & InfoNT.ComputerName & "/public/"
 sFolderURL = "appfolder/"
 sSchemaFolderURL = "schema/"

 Conn.Provider = "ExOLEDb.DataSource"
 Conn.Open  sVrootURL

 Set oRec = CreateObject("ADODB.Record")
 oRec.Open sVrootURL & sFolderURL, Conn, adModeReadWrite, adCreateCollection OR adCreateOverWrite

 oRec.Fields("DAV:contentclass") = "urn:content-classes:folder"

 '''''''''''''''''''''''''''''''''''''''''''''
 ' Here the schema-collection-ref URL is set.'
 '                                           '
 '''''''''''''''''''''''''''''''''''''''''''''
 oRec.Fields("urn:schemas-microsoft-com:exch-data:schema-collection-ref") = _
   sVrootURL & sFolderURL & sSchemaFolderURL

 oRec.Fields.Update

 Set oRec2 = CreateObject("ADODB.Record")
 oRec2.Open sVrootURL & sFolderURL & sSchemaFolderURL, Conn, adModeReadWrite, adCreateCollection OR adCreateOverWrite
 oRec2.Fields("DAV:contentclass") = "urn:content-classes:folder"
 oRec2.Fields("urn:schemas-microsoft-com:exch-data:baseschema").Value = Array( sVrootURL & "non_ipm_subtree/Schema")
 oRec2.Fields.Update

 wscript.echo oRec.Fields("urn:schemas-microsoft-com:exch-data:schema-collection-ref")

</script>
</Job>

C++

#import <msado15.dll> no_namespace
#import "c:\program files\common files\microsoft shared\cdo\cdoex.dll" no_namespace
#include <iostream.h>

void setSchemaColRef(bstr_t sFolderUrl) {

   _RecordPtr Rec(__uuidof(Record));
   _ConnectionPtr Conn(__uuidof(Connection));

   Conn->Provider = "ExOLEDB.DataSource";
   try {
      Conn->Open(sFolderUrl, bstr_t(), bstr_t(), -1);
   }
   catch(_com_error e) {
      cout << "Error opening connection." << endl;
      //..
      throw e;
   }

   try {
      Rec->Open(sFolderUrl,
            variant_t((IDispatch*)Conn,true),
            adModeReadWrite,
            adFailIfNotExists,
            adOpenSource,
            bstr_t(),
            bstr_t());
   }
   catch(_com_error e) {
      cout << "Error opening item" << endl;
      //..
   }

   FieldsPtr Flds;
   Flds = Rec->Fields;
   FieldPtr Fld;
   Fld = Flds->Item["urn:schemas-microsoft-com:exch-data:schema-collection-ref"];
   Fld->Value = bstr_t("http://server.microsoft.com/vroot/path/to/collection/");

   try {
      Flds->Update();
   }
   catch(_com_error e) {
      cout << "update failed" << endl;
      cout << e.Description() << endl;
   }

}

Related Topics

  • Web Storage System Schema

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Setting the Base Schema Path for a Schema Folder

The following example demonstrates how to set the urn:schemas-microsoft-com:baseschema property for a folder. This property indicates the Uniform Resource Identifier (URI)s of folders that contain additional schema definition items. The order in which these folder URIs appear in the property is the order in which these folders are searched.

If you define your own schema definition items and place them in your own set of schema folders, make sure that one of your schema folders has the base schema property set to the non_ipm_subtree/Schema folder for that store. If not, the global schema definitions will not be in the schema scope.

VBScript

<Job id="SetupFolderschema">
<reference object="adodb.record"/>

<script language="vbscript">

 Option Explicit

 Dim Info
 Dim InfoNT
 Dim oRec
 Dim oRec2
 Dim Conn
 Dim sVrootURL
 Dim sFolderURL
 Dim sSchemaFolderURL

 Set Info   = CreateObject("ADSystemInfo")
 Set InfoNT = CreateObject("WinNTSystemInfo")
 Set Conn   = CreateObject("ADODB.Connection")

 sVrootURL = "http://" & InfoNT.ComputerName & "/public/"
 sFolderURL = "appfolder/"
 sSchemaFolderURL = "schema/"

 Conn.Provider = "ExOLEDb.DataSource"
 Conn.Open  sVrootURL

 Set oRec = CreateObject("ADODB.Record")
 oRec.Open sVrootURL & sFolderURL, Conn, adModeReadWrite, adCreateCollection OR adCreateOverWrite

 oRec.Fields("DAV:contentclass") = "urn:content-classes:folder"
 oRec.Fields("urn:schemas-microsoft-com:exch-data:schema-collection-ref") = _
   sVrootURL & sFolderURL & sSchemaFolderURL
 oRec.Fields.Update

 Set oRec2 = CreateObject("ADODB.Record")
 oRec2.Open sVrootURL & sFolderURL & sSchemaFolderURL, Conn, adModeReadWrite, adCreateCollection OR adCreateOverWrite
 oRec2.Fields("DAV:contentclass") = "urn:content-classes:folder"

 '''''''''''''''''''''''''''''''''''''''''''''
 ' Here the baseschema array of URLs is set. '
 '                                           '
 '''''''''''''''''''''''''''''''''''''''''''''
 oRec2.Fields("urn:schemas-microsoft-com:exch-data:baseschema").Value = Array( sVrootURL & "non_ipm_subtree/Schema")

 oRec2.Fields.Update

 wscript.echo oRec.Fields("urn:schemas-microsoft-com:exch-data:schema-collection-ref")

</script>
</Job>

C++

#import <msado15.dll> no_namespace
#import "c:\program files\common files\microsoft shared\cdo\cdoex.dll" no_namespace
#include <iostream.h>

void setBaseSchemaForFolder(bstr_t sFolderUrl) {

   _RecordPtr Rec(__uuidof(Record));
   _ConnectionPtr Conn(__uuidof(Connection));

   Conn->Provider = "ExOLEDB.DataSource";
   try {
      Conn->Open(sFolderUrl, bstr_t(), bstr_t(), -1);
   }
   catch(_com_error e) {
      cout << "Error opening connection." << endl;
      //..
      throw e;
   }

   wchar_t* url1 =   L"http://server/public/test_folder2";
   wchar_t* url2 =   L"http://server/public/test_folder3";
   wchar_t* url3 =   L"http://server/public/non_ipm_subtree/Schema";

   VARIANT      vVal;
   VariantInit(&vVal);
   vVal.vt = VT_ARRAY | VT_VARIANT;

   SAFEARRAY* psa  = NULL;
   psa = SafeArrayCreateVector(VT_VARIANT, 0, 3);
   if(psa == NULL) {
      // handle error here.
   }

   VARIANT* pVal;
   HRESULT hr = S_OK;
   hr = SafeArrayAccessData(psa, (void**)&pVal);
   if(FAILED(hr)) {
      // handle error
   }

   VariantInit(&(pVal[0]));
   pVal[0].vt = VT_BSTR;
   pVal[0].bstrVal = SysAllocString(url1);
   VariantInit(&(pVal[1]));
   pVal[1].vt = VT_BSTR;
   pVal[1].bstrVal = SysAllocString(url2);
   VariantInit(&(pVal[2]));
   pVal[2].vt = VT_BSTR;
   pVal[2].bstrVal = SysAllocString(url3);

   SafeArrayUnaccessData(psa);

   vVal.parray = psa;

   try {
      Rec->Open(sFolderUrl,
            variant_t((IDispatch*)Conn,true),
            adModeReadWrite,
            adFailIfNotExists,
            adOpenSource,
            bstr_t(),
            bstr_t());
   }
   catch(_com_error e) {
      cout << "Error opening item" << endl;
      //..
   }

   FieldsPtr Flds;
   Flds = Rec->Fields;
   FieldPtr Fld;
   Fld = Flds->Item["urn:schemas-microsoft-com:exch-data:baseschema"];
   Fld->Value = vVal;

   SafeArrayDestroy(psa);
   VariantClear(&vVal);
   psa = NULL;

   try {
      Flds->Update();
   }
   catch(_com_error e) {
      cout << "update failed" << endl;
      cout << e.Description() << endl;
   }

   // Now, read the props back and print the values...
   variant_t vBaseSchema;
   vBaseSchema = Flds->Item["urn:schemas-microsoft-com:exch-data:baseschema"]->Value;
   if( ! (vBaseSchema.vt == (VT_ARRAY | VT_VARIANT))) {
      cout << "Unexpected..." << endl;
      // handle error
   }

   hr = SafeArrayAccessData(vBaseSchema.parray, (void**)&pVal);
   if(FAILED(hr)) {
      cout << "access data failed!!" << endl;
   }

   cout << "Set the baseschema property for the folder at \r\n  " << sFolderUrl;
   cout << " \r\nto the following URLS: " << endl;
   cout << bstr_t(pVal[0].bstrVal) << endl;
   cout << bstr_t(pVal[1].bstrVal) << endl;
   cout << bstr_t(pVal[2].bstrVal) << endl;

   SafeArrayUnaccessData(vBaseSchema.parray);

}

Related Topics

  • urn:schemas-microsoft-com:exch-data:baseschema
  • urn:schemas-microsoft-com:exch-data:schema-collection-ref
  • Web Storage System Schema

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Testing Your Schema

VBScript

<job id="testschema">
<reference object="adodb.record"/>
<script language="vbscript">

Dim InfoNT
Dim Conn
Dim Rec
Dim Rs
Dim strQ
Dim strURL
Set Conn = CreateObject("ADODB.Connection")
Conn.Provider = "ExOLEDB.DataSource"

Set Rs = CreateObject("ADODB.Recordset")
Set Rec = CreateObject("ADODB.Record")
Set InfoNT = CreateObject("WinNTSystemInfo")

strURL = "http://" & InfoNT.ComputerName & "/public/test_folder/"
Conn.Open strURL

Rec.Open strURL, Conn, adModeReadWrite
Rec.Fields("urn:schemas-microsoft-com:exch-data:schema-collection-ref") = strUrl & "schema"
Rec.Fields("urn:schemas-microsoft-com:exch-data:expected-content-class") = _
   Array("urn:schemas-domain-tld:content-classes:recipe")
Rec.Fields.Update
Rec.Close

Rec.Open strURL & "schema", Conn, adModeReadWrite
Rec.Fields("urn:schemas-microsoft-com:exch-data:baseschema") = Array(CStr("/public/non_ipm_subtree/Schema"))
Rec.Fields.Update
Rec.Close

Rec.Open strURL & "test1.txt", Conn, adModeReadWrite, adCreateNonCollection Or adCreateOverWrite
Rec.Fields("urn:schemas-domain-tld:title").Value      = "Title Here"
Rec.Fields("urn:schemas-domain-tld:submitdate").Value       = Now
Rec.Fields("urn:schemas-domain-tld:rating").Value           = CLng(4)
Rec.Fields("urn:schemas-domain-tld:cuisine").Value      = CStr("Cuisine Here")
Rec.Fields("urn:schemas-domain-tld:ingredients").Value  = Array("this", "that", "something-else")
Rec.Fields("urn:schemas-domain-tld:instructions").Value = CStr("The instructions here.")
Rec.Fields("DAV:contentclass") = "urn:schemas-domain-tld:content-classes:recipe"
Rec.Fields.Update
Rec.Close

Rec.Open strURL & "test1.txt", Conn
For Each Fld in Rec.Fields
 wscript.echo Fld.Name
 if not isarray(fld.value) then
   wscript.echo fld.value
 end if
Next

wscript.quit

strQ = "SELECT * from scope('shallow traversal of "
strQ = strQ & Chr(34) & strURL & Chr(34) & "') WHERE ""DAV:isfolder"" = False AND ""DAV:ishidden"" = False"

Rs.Open strQ, Conn
Rs.MoveFirst
Do Until Rs.EOF
   For x = 0 To Rs.Fields.Count - 1
      Wscript.Echo "Name: " & Rs(x).Name
      If VarType(Rs(x).Value) = vbString _
                  Or VarType(Rs(x).Value) = vbInteger _
                    Or VarType(Rs(x).Value) = vbLong _
                     Or VarType(Rs(x).Value) = vbDate Then
         Wscript.Echo "Value: " & Rs(x).Value
                Else
                  wscript.echo vartype(Rs(x).Value)
                End If
   Next
   Wscript.Echo "Next Record-----------------------"
   Rs.MoveNext
Loop

Rs.Close
</script>
</job>

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Importing Schema

This task demonstrates Microsoft Web Storage System programming capabilities. To import schema easily, use the Web Storage System Application Deployment Wizard.

The following code is for Windows Scripting Host file that has the following syntax:

cscript importxmlschema.wsf <file-system-folder> <store-folder-url>

The file system folder contains the defintions to import, and the store folder URL is the URL to the destination Web Storage System folder. The following is an example of the syntax:

cscript importxmlschema.wsf "c:\exchsrvr\schema" "file://./backofficestorage/%USERDNSDOMAIN%/pub2/test1/schema"

VBScript/JScript

<reference object="ADODB.Record"/>
<script language="vbscript">

Function getVBArray( t )

 l = t.valueOf()
 varr = split(l,",")
 getVBArray = varr

End Function

</script>

<script language="JScript">

 if( WScript.Arguments.Length < 2) {
  WScript.Echo("Usage: cscript importxmlschema.wsf <file-system-folder> <store-folder-url>");
  WScript.Quit();
 }

 var g_FolderRec;
 var filesystem_Folder = WScript.Arguments.Item(0);
 var schema_folderURL = WScript.Arguments.Item(1);

 WScript.Echo("Opening store folder at " + schema_folderURL);

 var g_FolderRec = new ActiveXObject("ADODB.Record");
 g_FolderRec.Open(schema_folderURL);

 WScript.Echo("getting files from " + filesystem_Folder);

 var fso = new ActiveXObject("Scripting.FilesystemObject");
 var fldr = fso.GetFolder(filesystem_Folder);

 var enum_fldr = new Enumerator(fldr.Files);
 for( ; ! enum_fldr.atEnd(); enum_fldr.moveNext()) {
   file = enum_fldr.item();
   WScript.Echo(file.Name);
   parseAndImport( file.Path );
 }

function parseAndImport( filePath ) {

 var Dom = new ActiveXObject("Microsoft.XMLDOM");
 Dom.validateOnParse = false;

 var bParseOkay = Dom.load(filePath);
 if(!bParseOkay) {
   WScript.Echo("Error parsing file");
   WScript.Echo(Dom.parseError.description);
   WScript.Echo(Dom.parseError.srcText);
   WScript.Quit();
 }

 importSchema( Dom , g_FolderRec, file.Name , Dom.xml);

}

function importSchema( Dom , fldrRec, itemName, sxml ) {
 Wscript.Echo("Importing schema from " + itemName + " into " + fldrRec.Fields("DAV:href"));
 var bIsContentClassDef = false;
 var ItemRec = new ActiveXObject("ADODB.Record");
 var itemURL = fldrRec.Fields("DAV:href").Value;
 if(itemURL.charAt(itemURL.length - 1) != "/")
   itemURL += "/";

 itemURL += itemName;
 ItemRec.Open(itemURL, fldrRec.ActiveConnection, adModeReadWrite, adCreateNonCollection | adCreateOverWrite);
 var Flds = ItemRec.Fields;

 var SchemaElem = Dom.documentElement;
 var nsMap = getPrefixMap(SchemaElem);
 var ElemType   = SchemaElem.selectSingleNode("ElementType");
 if(ElemType == null) {
  WScript.Echo("ElemType is null");
  WScript.Quit();
 }

 var propname = "";
 var propval  = "";

 var atts = ElemType.attributes;
 var t = true;
 while(t) {
  var n = atts.nextNode();
  if(n == null) {
    t = false;
    break;
  }
  if(n.namespaceURI == "")
    propname = buildStoreQName(n.baseName, nsMap.item("default"));
  else
    propname = buildStoreQName(n.baseName,n.namespaceURI);
  val = n.nodeValue;
  if(val.indexOf(":") != -1) {
    var parts = n.nodeValue.split(":");
    propval  = buildStoreQName(parts[1] , nsMap.item(parts[0]));
  }
  else {
    propval = n.nodeValue;
  }

  if(propname == "DAV:contentclass" && propval == "urn:content-classes:contentclassdef")
    bIsContentClassDef = true

  WScript.Echo(" Setting property: " + propname + ":" + propval);
  Flds.Item(propname) = propval;
 }

 /*
   The extends, element, and expected-content-class properties are multivalued
   for the contentclassdef item
 */

 if(bIsContentClassDef) {
  var Props = new ActiveXObject("Scripting.Dictionary");

  var Kids = ElemType.childNodes;
  var EKids = new Enumerator(Kids);
  var Kid;
  for( ; ! EKids.atEnd(); EKids.moveNext()) {
   Kid = EKids.item();
   propname =  buildStoreQName(Kid.baseName,Kid.namespaceURI);
   temp = Kid.getAttribute("type");
   if(temp.indexOf(":") != -1) {
     var parts = temp.split(":");
     propval  = buildStoreQName(parts[1] , nsMap.item(parts[0]));
   }
   else {
     propval = temp;
   }

   if(!Props.exists(propname)) {
     var pArray = new Array();
     pArray[0] = propval;
     Props.Add(propname, pArray);
   }
   else {
     var temp = Props.Item(propname);
     temp[temp.length] = propval;
   }
  }

  var PropEnum = new Enumerator(Props);
  var PropItem;
  for( ; !PropEnum.atEnd(); PropEnum.moveNext()) {
   PropItem = PropEnum.item();
   WScript.Echo(" Setting property: " + PropItem + ":");
   var t = Props.Item(PropItem);
   for ( v in t ) {
    WScript.Echo("    " + t[v]);
   }
   Flds.Item(PropItem) = getVBArray(Props.Item(PropItem));
  }
 }

 var Stm = Flds.Item(adDefaultStream).Value;
 Stm.WriteText(sxml);
 Stm.Flush();

 Flds.Update();
}

function getPrefixMap(root) {
 var pos1, pos2;
 var prefixMap = new ActiveXObject("Scripting.Dictionary");
 var atts = root.attributes;
 var en;
 en = new Enumerator(atts);

 var item;
 var name;
 for( ;!en.atEnd();en.moveNext()) {
   pos1 = -1;
   pos2 = -1;
   item = en.item();
   name = item.name;
   pos1 = name.indexOf("xmlns");
   if(pos1 > -1) {
     pos2 = name.indexOf("xmlns:", 0);
     if(pos2 == -1) {
      prefixMap.add("default",item.value);
     }
     else {
       name = name.substr(pos1 + 6);
       prefixMap.add(name,item.value);
     }
   }
 }

 return(prefixMap);
}

function buildStoreQName( ncname, nsURI) {
 var c = nsURI.charAt(nsURI.length - 1);
 var sep = "";
 if(":/".indexOf(c) < 0) {
  sep = "#";
 }
 return(nsURI + sep + ncname);
}
</script>

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Using Folder Content-Class

All Web Storage System folders and items have content class values that denote their intended purpose. A folder is an item that is a collection of other items. Web Storage System applications can use content class values to determine how to process the data that an item contains.

You can check the content class using an Microsoft® ActiveX® Data Objects (ADO) Record object before you create instances of any CDO objects. To do so, you can check the value of the DAV:contentclass property. Alternatively, if you know the item is a folder by checking its DAV:iscollection property values, you can create an instance of a CDO Folder object from a URL or from an ADO Record object and then check the IFolder.ContentClass property.

Visual Basic

Dim CC as String
Dim Rec As New ADODB.Record
With Rec
  .Open strFolderURL
  CC = .Fields("DAV:contentclass")
  If CC = "urn:content-classes:contactfolder" Then
   '
  Else If CC = "urn:content-classes:mailfolder" Then
   '
  End If
  Rec.Close
End With

  'To check a folder Content-Class using a CDO Folder object
Dim iFldr As New CDO.Folder
Dim iDsrc as CDO.IDataSource
Set iDsrc = iFldr
iDsrc.Open strFolderURL
If iFldr.ContentClass = "urn:content-classes:mailfolder" Then
   '
End If

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Security Tasks

The following topics describe how to manage security for items in the Web Storage System:

Getting an Item's XML Security Descriptor

Creating Web Storage System Descriptors in XML

Creating an ACE in XML

Modifying an Item's Discretionary Access Control List

Updating an Item's Security Descriptor

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Getting an Item's XML Security Descriptor

You can get an item's XML security descriptor by requesting the http://schemas.microsoft.com/exchange/security/descriptor property. The following example shows what the WebDAV request might look like:

PROPFIND /path/to/item.txt HTTP/1.1
Content-Type: text/xml
Depth: 0
Translate: f
Content-Length: XXX

<?xml version="1.0"?>
<propfind xmlns="DAV:">
 <prop xmlns:S="http://schemas.microsoft.com/exchange/security/">
  <S:descriptor/>
 </prop>
</propfind>

The following example demonstrates how to send this request by using the XMLHTTP Component Object Model (COM) object:

JScript

function getSecurityDescForItem( url , username, password) {

 var xmlDom = new ActiveXObject("Microsoft.XMLDOM");
 var pi     = xmlDom.createProcessingInstruction("xml","version=\"1.0\"");
 var e1     = xmlDom.createNode(1, "propfind", "DAV:");
 var e2     = xmlDom.createNode(1, "prop","DAV:");

 xmlDom.appendChild(pi);
 xmlDom.documentElement = e1;
 e1.setAttribute("xmlns:S","http://schemas.microsoft.com/exchange/security/");
 e1.appendChild(e2);
 e2.appendChild(xmlDom.createNode(1, "S:descriptor","http://schemas.microsoft.com/exchange/security/"));

 var Req = new ActiveXObject("Microsoft.XMLHTTP");

 Req.open("PROPFIND",url, false, username, password);
 Req.setRequestHeader("Content-Type","text/xml");
 Req.setRequestHeader("Depth","0");
 Req.setRequestHeader("Translate","f");

 Req.send(xmlDom.xml);

 if(Req.status != "207") {
   var errstr = "ERR: HTTP server returned status=" + Req.status
   errstr    += "\r\nError: HTTP server returned status=" + Req.status;
   errstr    += "       Status text: " + Req.statusText;
   errstr    += "       Response Text: " + Req.responseText;
   throw errstr;
 }

 var resItem   = findDescriptorInDOM(Req.responseXML);
 if(resItem == null)
   throw "ERR: Could not locate prop in response!!";
 else
   return resItem;
}

function findDescriptorInDOM( Doc ) {

 var item;
 var root = Doc.documentElement;
 if(root.namespaceURI != "DAV:")
   return null;

 var prefix = root.prefix;
 var propElem = root.selectSingleNode("//" + prefix + ":" + "prop");
 if(propElem == null)
   return null;

 var descProp = propElem.childNodes.item(0);
 if(descProp.baseName != "descriptor" || descProp.namespaceURI != "http://schemas.microsoft.com/exchange/security/")
  return null;

 var desc = descProp.childNodes.item(0);
 WScript.Echo(desc.nodeName);
 return desc;

}

The following example demonstrates how to get the item's security descriptor by using Microsoft® ActiveX® Data Objects (ADO) and the Microsoft® Exchange 2000 Server OLE DB provider:

VBScript

Function getSecDescForItem( vSource )

  Dim Rec
  Dim vtype
  dim typenam
  vtype = VarType(vSource)
  typenam = TypeName(vSource)

 ' Check arguments
  If Not ( _
    ( vtype = vbString) OR  _
    (  ( vtype = vbObject)  And  _
    (  ( typenam = "Record") ) ) _
    ) Then
    Err.Raise &H80070057 ' E_INVALIDARG
  End If

  if vtype = vbString Then
    Set Rec = CreateObject("ADODB.Record")
    Rec.Open vSource
  elseif vtype = vbObject And typename = "Record" Then
    Set Rec = vSource
  End If

  Dim Flds
  Set Flds = Rec.Fields
  getSecDescForItem = Flds("http://schemas.microsoft.com/exchange/security/descriptor").Value

End Sub

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Creating Web Storage System Descriptors in XML

To construct Web Storage System item security descriptors in XML, you need only create the appropriate XML elements and XML document described in Web Storage System Security. The following sections show how to create various XML descriptor elements using the Microsoft MSXML DOM parser:

Creating an ACE in XML

Modifying an Item's Discretionary Access Control List

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Creating an ACE in XML

There are two types of access control entries (ACEs) used in the XML security descriptor format. The access_allowed_ace element grants a trustee an access right, and the access_denied_ace element denies a trustee an access right.

The following example demonstrates how to create an access control entry for a Web Storage System XML-formatted security descriptor:

JScript

function createXMLAce(  XMLDom, prefix, bAccessAllowed, username, mask ) {

 var eAce;
 var eMask;
 var eId;

 if(XMLDom == null)
   throw "ERR: XMLDOMDocument passed was null";

 if(prefix != "")
   prefix += ":";

 if(bAccessAllowed)
   eAce = XMLDom.createNode(1,prefix +"access_allowed_ace", "http://schemas.microsoft.com/security/");
 else
   eAce = XMLDom.createNode(1,prefix +"access_denied_ace", "http://schemas.microsoft.com/security/");

 if(eAce == null)
   throw "ERR: created ACE was null!";

 eMask = getXMLMask(XMLDom, prefix, mask);
 eSid   = getXMLSID(XMLDom, prefix, username);
 eAce.appendChild(eMask);
 eAce.appendChild(eSid);
 return eAce;
}

function getXMLMask(XMLDom, prefix, mask) {

 var eMask = XMLDom.createNode(1, prefix + "access_mask", "http://schemas.microsoft.com/security/");
 eMask.appendChild(XMLDom.createTextNode(mask));
 return eMask;
}

function getXMLSID(XMLDom, prefix, username) {

 var eSid = XMLDom.createNode(1,prefix + "sid", "http://schemas.microsoft.com/security/");
 var eName;
 eName = XMLDom.createNode(1, prefix + "nt4_compatible_name", "http://schemas.microsoft.com/security/");
 eName.appendChild(XMLDom.createTextNode(username));
 eSid.appendChild(eName);

 return eSid;

}

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Modifying an Item's Discretionary Access Control List

To modify an item's discretionary access control list (DACL), you manage the access control entries in the effective_aces, subcontainer_inheritable_aces, and subitem_inheritable_aces sections of the DACL.

The following example demonstrates how to add access-allowed and access-denied ACEs to an item's DACL.

JScript

function addAccessAllowedAce( XMLDomDescriptor, sdACEElem ) {
 var p = XMLDomDescriptor.documentElement.prefix;
 WScript.Echo("descriptor prefix: " + prefix);
 if(p != "")
  p += ":";
 var daclElem = XMLDomDescriptor.selectSingleNode("/"+p+"security_descriptor/"+p+"dacl");
 if(daclElem == null)
  throw "ERR: No discretionary access control list in descriptor";

 var effAcesElem = daclElem.selectSingleNode(p+"effective_aces");
 if(effAcesElem == null)
   throw "ERR: No effective aces!";

 effAcesElem.appendChild(sdACEElem);

 return;
}

function addAccessDeniedAce( XMLDomDescriptor, sdACEElem ) {
 var p = XMLDomDescriptor.documentElement.prefix;
 WScript.Echo("descriptor prefix: " + prefix);
 if(p != "")
  p += ":";
 var daclElem = XMLDomDescriptor.selectSingleNode("/"+p+"security_descriptor/"+p+"dacl");
 if(daclElem == null)
  throw "ERR: No discretionary access control list in descriptor";

 var effAcesElem = daclElem.selectSingleNode(p+"effective_aces");
 if(effAcesElem == null)
   throw "ERR: No effective aces!";

 effAcesElem.insertBefore( sdACEElem , effAcesElem.firstChild);

 return;
}

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Updating an Item's Security Descriptor

To update an item's security descriptor, you need only modify the XML representation of the descriptor and save the updated XML back to the item's http://schemas.microsoft.com/exchange/security/descriptor property. To update the respective parts of the item's descriptor, you must have the proper access rights (READ_CONTROL, WRITE_DAC, or WRITE_OWNER).

If you want to update only a portion of an item's security descriptor, you can leave out the other sections of the descriptor in the XML stream. For example, if you want to update only the discretionary access control list (DACL) for an item, you can leave out the <S:owner>, <S:group>, and <S:sacl> portions in the XML stream. When an entire section is not present in the update XML, this portion of the item's descriptor does not change.

The following example demonstrates how to update an item's security descriptor.

JScript

/*
** putSecurityDescForItem

** This function uses the WebDAV protocol to update
** an item's http://schemas.microsoft.com/exchange/security/descriptor
** property.
**   url      - URL to the item.
**   vSource  - Either XML text or an XMLDOM object reference.
**   username - Username used to authenticate with IIS.
**   password - Password used to authenticate with IIS.
*/
function putSecurityDescForItem( url , vSource , username, password) {

 var sendXMLDOM;
 if(typeof(vSource) == "string") {
   sendXMLDOM = new ActiveXObject("Microsoft.XMLDOM");
   sendXMLDOM.loadXML(vSource);
 }
 else if(typeof(vSource) == "object") {
   sendXMLDOM = vSource;
 }
 else {
  throw "ERR-putSecurityDescForItem: Invalid Argument";
 }

 var xmlDom = new ActiveXObject("Microsoft.XMLDOM");
 var pi     = xmlDom.createProcessingInstruction("xml","version=\"1.0\"");
 var root   = xmlDom.createNode(1, "propertyupdate", "DAV:");
 var e1     = xmlDom.createNode(1, "set","DAV:");
 var e2     = xmlDom.createNode(1, "prop", "DAV:");
 var e3    =  xmlDom.createNode(1, "a:descriptor","http://schemas.microsoft.com/exchange/security/");

 root.appendChild(e1);
 e1.appendChild(e2);
 e2.appendChild(e3);
 e3.appendChild(sendXMLDOM.documentElement);

 xmlDom.appendChild(pi);
 xmlDom.documentElement = root;

 var Req = new ActiveXObject("Microsoft.XMLHTTP");
 Req.open("PROPPATCH", url, false, username, password);
 Req.setRequestHeader("Content-Type","text/xml");
 Req.setRequestHeader("Translate","f");
 Req.send(xmlDom.xml);

 if(Req.status != "207") {
   var errstr = "ERR: HTTP server returned status=" + Req.status
   errstr    += "\r\nError: HTTP server returned status=" + Req.status;
   errstr    += "       Status text: " + Req.statusText;
   errstr    += "       Response Text: " + Req.responseText;
   throw errstr;
 }

 return Req.responseXML;

}

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Using Web Storage System Events

You can include the Exchange OLE DB (ExOLEDB) type library (EXOLEDB.DLL) in any Microsoft® Visual Basic® project.

In implementing your Visual Basic event sinks in a Component Object Model (COM) class, you name event methods by prefixing the event names with the interface name. Use the following event method names:

IExStoreSyncEvents_OnSyncSave
IExStoreSyncEvents_OnSyncDelete
IExStoreAsyncEvents_OnSave
IExStoreAsyncEvents_OnDelete
IExStoreSystemEvents_OnMDBStartUp
IExStoreSystemEvents_OnMDBShutDown
IExStoreSystemEvents_OnTimer

When implementing event methods as scripts, you prefix all event methods with "ExStoreEvents_". For example, the OnSyncSave event in a script would be ExStoreEvents_OnSyncSave.

For examples of how to implement event sink methods in a script or event sink interfaces in a COM class, use the following links:

Implementing Synchronous Event Sinks

Implementing Asynchronous Event Sinks

Implementing System Event Sinks

For examples of how to create and manage event registrations, use the following links:

Managing Event Registrations

Managing Event Registrations with RegEvent.vbs

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Implementing Synchronous Event Sinks

A synchronous event occurs before the specified event is committed to the store, thus giving you a chance to abort the event if necessary. The OnSyncSave event also gives you a chance to check or modify the data before you save it. For examples of implementing synchronous event sinks, use the following links:

Implementing an OnSyncSave Event Sink

Implementing an OnSyncDelete Event Sink

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Implementing an OnSyncSave Event Sink

A synchronous event is called once for the beginning phase of the specified event and then again to either commit or abort it. The EVT_NEW_ITEM flag is set for the first time this specific event is called for this event registration. The following example illustrates the basic structure of synchronous events.

Visual Basic

Private Sub IExStoreSyncEvents_OnSyncSave(ByVal pEventInfo As Exoledb.IExStoreEventInfo, ByVal bstrURLItem As String, ByVal lFlags As Long)

    Dim FSO         As Object
    Dim EvtLog      As String
    Dim EvtFile
    Dim DispEvtInfo As IExStoreDispEventInfo
    Dim ADODBRec    As ADODB.Record

    Set DispEvtInfo = pEventInfo

'Log file
    EvtLog = Environ("SystemDrive") & "\OnSyncSave.log"

'Creates new log file %SystemDrive%\OnSyncSave.log or opens it if exists
    Set FSO = CreateObject("Scripting.FileSystemObject")
    Set EvtFile = FSO.OpenTextFile(EvtLog, 8, True)

'Append incoming event info into log file
    EvtFile.WriteLine ("[VB Event Sink]          OnSyncSave()")
    EvtFile.WriteLine ("  URL Item:              " & bstrURLItem)
    EvtFile.WriteLine ("  lFlags:                " & "0x" & Hex(lFlags))

'Small sample that shows how to use ADO Record Object and Fields inside events
    Set ADODBRec = DispEvtInfo.EventRecord
    EvtFile.WriteLine ("  DAV:Displayname Value: " & ADODBRec.Fields("DAV:displayname").Value)

'To determine type of incoming OnSyncSave notifications:

    'Case 1: EVT_SYNC_BEGIN
    If lFlags And EVT_SYNC_BEGIN Then
        'Perform your tasks
        'Begin phase of OnSyncSave for a resource
        EvtFile.WriteLine ("  Flag contains EVT_SYNC_BEGIN bit set")

    'Case 2: EVT_SYNC_COMMITTED
    ElseIf lFlags And EVT_SYNC_COMMITTED Then
        'Perform your tasks
        'Commit phase of OnSyncSave for a resource
        EvtFile.WriteLine ("  Flag contains EVT_SYNC_COMMITTED bit set")

    'Case 3: EVT_SYNC_ABORTED
    ElseIf lFlags And EVT_SYNC_ABORTED Then
        'Perform your tasks
        'Abort phase of OnSyncSave for item that is getting aborted
        EvtFile.WriteLine ("  Flag contains EVT_SYNC_ABORTED bit set")

    End If

'To determine cause of OnSyncSave

    'Case 1: EVT_IS_DELIVERED
    If lFlags And EVT_IS_DELIVERED Then
        'Perform your tasks
        'OnSyncSave for delivered mail item
        EvtFile.WriteLine ("  Flag contains EVT_IS_DELIVERED bit set")

    'Case 2: EVT_MOVE
    ElseIf lFlags And EVT_MOVE Then
        'Perform your tasks
        'OnSyncSave for moved item
        EvtFile.WriteLine ("  Flag contains EVT_MOVE bit set")

    'Case 3: EVT_COPY
    ElseIf lFlags And EVT_COPY Then
        'Perform your tasks
        'OnSyncSave for copied item
        EvtFile.WriteLine ("  Flag contains EVT_COPY bit set")

    End If

    'Check if it is folder notification
    If lFlags And &H2 Then
        'Perform your tasks
        'OnSyncSave for a folder
        EvtFile.WriteLine ("  Flag contains EVT_IS_COLLECTION bit set")
    End If

    EvtFile.WriteBlankLines (1)

'Before Quit
    EvtFile.Close
    Set FSO = Nothing
    Set DispEvtInfo = Nothing

End Sub

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Implementing an OnSyncDelete Event Sink

The following example handles the OnSyncDelete event:

Visual Basic

Private Sub IExStoreSyncEvents_OnSyncDelete(ByVal pEventInfo As Exoledb.IExStoreEventInfo, ByVal bstrURLItem As String, ByVal lFlags As Long)

    Dim FSO         As Object
    Dim EvtLog      As String
    Dim EvtFile

'Log file
    EvtLog = Environ("SystemDrive") & "\OnSyncDelete.log"

'Creates new log file %SystemDrive%\OnSyncDelete.log or opens it if exists
    Set FSO = CreateObject("Scripting.FileSystemObject")
    Set EvtFile = FSO.OpenTextFile(EvtLog, 8, True)

'Append incoming event info into log file
    EvtFile.WriteLine ("[VB Event Sink]          OnSyncDelete()")
    EvtFile.WriteLine ("  URL Item:              " & bstrURLItem)
    EvtFile.WriteLine ("  lFlags:                " & "0x" & Hex(lFlags))

'To determine type of incoming OnSyncDelete notifications:

    'Case 1: EVT_SYNC_BEGIN
    If lFlags And EVT_SYNC_BEGIN Then
        'Perform your tasks
        'Begin phase of OnSyncDelete
        EvtFile.WriteLine ("  Flag contains EVT_SYNC_BEGIN bit set")

    'Case 2: EVT_SYNC_COMMITTED
    ElseIf lFlags And EVT_SYNC_COMMITTED Then
        'Perform your tasks
        'Commit phase of OnSyncDelete
        EvtFile.WriteLine ("  Flag contains EVT_SYNC_COMMITTED bit set")

    'Case 3: EVT_SYNC_ABORTED
    ElseIf lFlags And EVT_SYNC_ABORTED Then
        'Perform your tasks
        'Abort phase of OnSyncDelete
        EvtFile.WriteLine ("  Flag contains EVT_SYNC_ABORTED bit set")

    End If

'To determine type of OnSyncDelete

    'EVT_SOFTDELETE
    If lFlags And EVT_SOFTDELETE Then
        'Perform your tasks
        EvtFile.WriteLine ("  Flag contains EVT_SOFTDELETE bit set")
    End If

    'EVT_HARDDELETE
    If lFlags And EVT_HARDDELETE Then
        'Perform your tasks
        EvtFile.WriteLine ("  Flag contains EVT_HARDDELETE bit set")
    End If

     'Check if it is a folder notification
    If lFlags And EVT_IS_COLLECTION Then
        'Perform your tasks
        'OnSyncDelete for a folder
        EvtFile.WriteLine ("  Flag contains EVT_IS_COLLECTION bit set")
    End If

    EvtFile.WriteBlankLines (1)

'Before Quit
    EvtFile.Close
    Set FSO = Nothing

End Sub

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Implementing Asynchronous Event Sinks

An asynchronous event occurs after the specified event is committed to the store. For examples of implementing asynchronous event sinks, use the following links:

Implementing an OnSave Event Sink

Implementing an OnDelete Event Sink

Note The naming convention for event methods is always Interfacename_Eventname.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Implementing an OnSave Event Sink

The following code receives the OnSave event and returns information about it:

Visual Basic

Private Sub IExStoreAsyncEvents_OnSave(ByVal pEventInfo As Exoledb.IExStoreEventInfo, ByVal bstrURLItem As String, ByVal lFlags As Long)

    Dim FSO         As Object
    Dim EvtLog      As String
    Dim EvtFile
    Dim DispEvtInfo As IExStoreDispEventInfo
    Dim ADODBRec    As ADODB.Record

    Set DispEvtInfo = pEventInfo

'log file
    EvtLog = Environ("SystemDrive") & "\OnSave.log"

'Creates new log file %SystemDrive%\OnSave.log or opens it if exists
    Set FSO = CreateObject("Scripting.FileSystemObject")
    Set EvtFile = FSO.OpenTextFile(EvtLog, 8, True)

'Append incoming event info into log file
    EvtFile.WriteLine ("[VB Event Sink]          OnSave()")
    EvtFile.WriteLine ("  URL Item:              " & bstrURLItem)
    EvtFile.WriteLine ("  lFlags:                " & "0x" & Hex(lFlags))

'Small sample that shows how to use ADO Record Object and Fields inside events
    Set ADODBRec = DispEvtInfo.EventRecord
    EvtFile.WriteLine ("  DAV:Displayname Value: " & ADODBRec.Fields("DAV:displayname").Value)

'To determine cause of OnSyncSave

    'Case 1: EVT_IS_DELIVERED
    If lFlags And EVT_IS_DELIVERED Then
        'Perform your tasks
        'OnSave for delivered mail item
        EvtFile.WriteLine ("  Flag contains EVT_IS_DELIVERED bit set")

    'Case 2: EVT_MOVE
    ElseIf lFlags And EVT_MOVE Then
        'Perform your tasks
        'OnSave for moved item
        EvtFile.WriteLine ("  Flag contains EVT_MOVE bit set")

    'Case 3: EVT_COPY
    ElseIf lFlags And EVT_COPY Then
        'Perform your tasks
        'OnSave for copied item
        EvtFile.WriteLine ("  Flag contains EVT_COPY bit set")

    End If

    'Check if it is a folder notification
    If lFlags And &H2 Then
        'Perform your tasks
        'OnSave for a folder
        EvtFile.WriteLine ("  Flag contains EVT_IS_COLLECTION bit set")
    End If

    EvtFile.WriteBlankLines (1)

    'Use the sink context (custom contextual info saved in the registration item)
    Dim case_switch As Integer
    Dim notify_group As String

    Const customnamespace = "mycustomnamespace:eventsinks/notifyingevents/"
    Dim propname As String

    propname = customnamespace + "caseswitch"
    case_switch = ADODBRec.Fields(propname)

    propname = customnamespace + "notifygroup"
    notify_group = ADODBRec.Fields(propname)

    'Call some program here to use the custom data to notify people of an event
    'Something like: handle_notifyevent(case_switch, notify_group)

'Before Quit
    EvtFile.Close
    Set FSO = Nothing
    Set DispEvtInfo = Nothing

End Sub

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Implementing an OnDelete Event Sink

The following code receives the OnDelete event and returns information about it:

Visual Basic

Private Sub IExStoreAsyncEvents_OnDelete(ByVal pEventInfo As Exoledb.IExStoreEventInfo, ByVal bstrURLItem As String, ByVal lFlags As Long)

    Dim FSO         As Object
    Dim EvtLog      As String
    Dim EvtFile

'log file
    EvtLog = Environ("SystemDrive") & "\OnDelete.log"

'Creates new log file %SystemDrive%\OnDelete.log or opens it if exists
    Set FSO = CreateObject("Scripting.FileSystemObject")
    Set EvtFile = FSO.OpenTextFile(EvtLog, 8, True)

'Append incoming event info into log file
    EvtFile.WriteLine ("[VB Event Sink]          OnDelete()")
    EvtFile.WriteLine ("  URL Item:              " & bstrURLItem)
    EvtFile.WriteLine ("  lFlags:                " & "0x" & Hex(lFlags))

'To determine type of OnDelete

    'Case 1: EVT_SOFTDELETE
    If lFlags And EVT_SOFTDELETE Then
        'Perform your tasks
        EvtFile.WriteLine ("  Flag contains EVT_SOFTDELETE bit set")
    End If

    'Case 2: EVT_HARDDELETE
    If lFlags And EVT_HARDDELETE Then
        'Perform your tasks
        EvtFile.WriteLine ("  Flag contains EVT_HARDDELETE bit set")
    End If

    'Check if it is a folder notification
    If lFlags And EVT_IS_COLLECTION Then
        'Perform your tasks
        'OnDelete for a folder
        EvtFile.WriteLine ("  Flag contains EVT_IS_COLLECTION bit set")
    End If

    EvtFile.WriteBlankLines (1)

'Before Quit
    EvtFile.Close
    Set FSO = Nothing

End Sub

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Implementing System Event Sinks

For examples of how to handle and log system events, use the following links:

Implementing an OnMdbStartup Event Sink

Implementing an OnMdbShutdown Event Sink

Implementing an OnTimer Event Sink

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Implementing an OnMdbStartup Event Sink

The following code handles and logs the OnMdbStartup system event:

Visual Basic

Private Sub IExStoreSystemEvents_OnMDBStartUp(ByVal bstrMDBGuid As String, ByVal bstrMDBName As String, ByVal lFlags As Long)

    Dim FSO         As Object
    Dim EvtLog      As String
    Dim EvtFile

'Log file
    EvtLog = Environ("SystemDrive") & "\OnMDBStartUp.log"

'Creates new log file %SystemDrive%\OnMDBStartUp.log or opens it if exists
    Set FSO = CreateObject("Scripting.FileSystemObject")
    Set EvtFile = FSO.OpenTextFile(EvtLog, 8, True)

'Append incoming event info into log file
    EvtFile.WriteLine ("[VB Event Sink]          OnMDBStartUp()")
    EvtFile.WriteLine ("  MDB Guid               " & bstrMDBGuid)
    EvtFile.WriteLine ("  MDB Name               " & bstrMDBName)
    EvtFile.WriteLine ("  lFlags:                " & "0x" & Hex(lFlags))

    EvtFile.WriteBlankLines (1)

'Before Quit
    EvtFile.Close
    Set FSO = Nothing

End Sub

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Implementing an OnMdbShutdown Event Sink

The following code handles and logs the OnMdbShutdown system event:

Visual Basic

Private Sub IExStoreSystemEvents_OnMDBShutDown(ByVal bstrMDBGuid As String, ByVal lFlags As Long)

    Dim FSO         As Object
    Dim EvtLog      As String
    Dim EvtFile

'log file
    EvtLog = Environ("SystemDrive") & "\OnMDBShutDown.log"

'Creates new log file %SystemDrive%\OnMDBShutDown.log or opens it if exists
    Set FSO = CreateObject("Scripting.FileSystemObject")
    Set EvtFile = FSO.OpenTextFile(EvtLog, 8, True)

'Append incoming event info into log file
    EvtFile.WriteLine ("[VB Event Sink]          OnMDBShutDown()")
    EvtFile.WriteLine ("  MDB Guid               " & bstrMDBGuid)
    EvtFile.WriteLine ("  lFlags:                " & "0x" & Hex(lFlags))

    EvtFile.WriteBlankLines (1)

'Before Quit
    EvtFile.Close
    Set FSO = Nothing

End Sub

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Implementing an OnTimer Event Sink

The following code handles and logs the OnTimer system event:

Visual Basic

Private Sub IExStoreSystemEvents_OnTimer(ByVal bstrURLItem As String, ByVal lFlags As Long)

    Dim FSO         As Object
    Dim EvtLog      As String
    Dim EvtFile

'Log file
    EvtLog = Environ("SystemDrive") & "\OnTimer.log"

'Creates new log file %SystemDrive%\OnTimer.log or opens it if exists
    Set FSO = CreateObject("Scripting.FileSystemObject")
    Set EvtFile = FSO.OpenTextFile(EvtLog, 8, True)

'Append incoming event info into log file
    EvtFile.WriteLine ("[VB Event Sink]          OnTimer()")
    EvtFile.WriteLine ("  lFlags:                " & "0x" & Hex(lFlags))

    EvtFile.WriteBlankLines (1)

'Before Quit
    EvtFile.Close
    Set FSO = Nothing

End Sub

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Managing Event Registrations

For examples of how to add, enumerate, and delete event sink registrations, use the following links:

Adding an Event Registration for a Folder

Removing an Event Registration for a Folder

Enumerating Event Registrations for a Folder

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Adding an Event Registration for a Folder

The following code creates a store item, sets its content class and schema, and saves it to the store. The store then processes the event registration. For more information, see Event Registration.

Visual Basic

'=============================================================================='
' This subroutine creates the event binding in the meta-database
' by setting properties in an event registration item and committing it to the
' store.  The event of saving the item triggers the event registration
' event sink, which processes the event registration and sets the registration
' to hidden so that it does not appear in the store folder.
'=============================================================================='
Sub AddNewStoreEvent(Server As String)
    On Error Resume Next

    'heres a list of the properties you can set for the registration event item
    'not all of these are used in this example
    Const propcontentclass = "DAV: contentclass"

    Const propCriteria = "http://schemas.microsoft.com/exchange/events/Criteria"
    Const propEnabled = "http://schemas.microsoft.com/exchange/events/Enabled"
    Const propEventMethod = "http://schemas.microsoft.com/exchange/events/EventMethod"
    Const propMatchScope = "http://schemas.microsoft.com/exchange/events/MatchScope"
    Const propPriority = "http://schemas.microsoft.com/exchange/events/Priority"
    Const propScriptURL = "http://schemas.microsoft.com/exchange/events/ScriptUrl"
    Const propSinkClass = "http://schemas.microsoft.com/exchange/events/SinkClass"
    Const propTimerExpiryTime = "http://schemas.microsoft.com/exchange/events/TimerExpiryTime"
    Const propTimerInterval = "http://schemas.microsoft.com/exchange/events/TimerInterval"
    Const propTimerStartTime = "http://schemas.microsoft.com/exchange/events/TimerStartTime"

    Dim cn As New ADODB.Connection
    Dim rEvent As New ADODB.Record
    Dim strGuid
    Dim strBaseUrl
    Dim strEvent

    'This will serve as the scope as well
    '(Where you save it is where the event fires)
    strBaseUrl = "file://./backofficestorage/" + _
                 Server + _
                 "/public folders/internet newsgroups"

    strEvent = strBaseUrl + "/evtreg1" 'evtreg1 is the item name

    ' Create the connection
    cn.Provider = "exoledb.datasource"
    cn.ConnectionString = strBaseUrl
    cn.Open
    If Err.Number <> 0 Then
      MsgBox "Error Opening Connection : " & Err.Number & " " & Err.Description & vbCrLf
      Exit Sub
    End If

    cn.BeginTrans
    rEvent.Open strEvent, cn, 3, 0     ' adModeReadWrite, adCreateNonCollection
    If Err.Number <> 0 Then
      MsgBox "Error Opening Record : " & Err.Number & " " & Err.Description & vbCrLf
      Exit Sub
    End If

    'set the properties in the item
    With rEvent.Fields
      .Item(propcontentclass) = "urn:content-class:storeeventreg"
      .Item(propEventMethod) = "onsave;ondelete" 'register for both save and delete events
      .Item(propSinkClass) = "VB_OutProc.sink"  'your registered event handler sink class ProgID

      'match scope
      .Item(propMatchScope) = "deep"
      .Item(propCriteria) = "WHERE $DAV:ishidden$ = FALSE"

      'Add custom properties which the event sink can use to
      'determine the context of this event registration

      Const customnamespace = "mycustomnamespace:eventsinks/notifyingevents/"
      Dim propname As String
      propname = customnamespace + "caseswitch"
      .Append propname, adInteger, , , 2         'for a case switch in the event sink
      propname = customnamespace + "notifygroup"
      .Append propname, adChar, , , "Marketing"  'a group you've created in exchange

      MsgBox "New Event Binding with custom properties created."

      .Update  'get the ADO object current
      If Err.Number <> 0 Then
        MsgBox "Error Updating Props : " & Err.Number & " " & Err.Description & vbCrLf
        Exit Sub
      End If

    End With
    cn.CommitTrans  'commit transaction to the store

    If Err.Number <> 0 Then
      MsgBox "Error Commiting Transaction : " & Err.Number & " " & Err.Description & vbCrLf
      Exit Sub
    End If

End Sub

During the process of adding an event registration for a folder, contextual information about this specific registration is also added. You can access this information from within the event sink. For more information, see Contextual Information in an Event Registration.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Removing an Event Registration for a Folder

To remove an event sink, you delete the item, using code similar to the following sample:

Visual Basic

  'All you have to do is delete the registration item
Private Sub DeleteEvent(Server As String)
    On Error Resume Next

    'here is a handy list of the properties you can set for the registration event item
    'not all of these are used in this example

    Dim cn   As New ADODB.Connection
    Dim rEvent As New ADODB.Record
    Dim strGuid
    Dim strBaseUrl
    Dim strEvent

    'this will serve as the scope as well
    strBaseUrl = "file://./backofficestorage/" + _
                 Server + _
                 "/public folders/internet newsgroups"

    strEvent = strBaseUrl + "/evtreg1" 'evtreg1 is the item name

    ' Create the connection
    cn.Provider = "exoledb.datasource"
    cn.ConnectionString = strBaseUrl
    cn.Open
    If Err.Number <> 0 Then
      MsgBox "Error Opening Connection : " & Err.Number & " " & Err.Description & vbCrLf
      Exit Sub
    End If

    cn.BeginTrans

    rEvent.Open strEvent, cn, 3, 0     ' adModeReadWrite, adCreateNonCollection
    If Err.Number <> 0 Then
      MsgBox "Error Opening Record : " & Err.Number & " " & Err.Description & vbCrLf
      Exit Sub
    End If

    rEvent.DeleteRecord

    cn.CommitTrans  'commit transaction to the store

    If Err.Number <> 0 Then
      MsgBox "Error Commiting Transaction : " & Err.Number & " " & Err.Description & vbCrLf
      Exit Sub
    End If

End Sub

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Enumerating Event Registrations for a Folder

The following code opens an event registration item and lists the events it is registering.

Visual Basic

Public Sub Enum_Event(Server As String)
  On Error Resume Next
  Dim Query
  Dim fld

  Dim rs As New ADODB.Recordset
  Dim strParentFolder
  Dim strEventRegistrationName
  Dim aPropNames

  aPropNames = Array( _
    "DAV:contentclass", _
    "http://schemas.microsoft.com/exchange/events/Criteria", _
    "http://schemas.microsoft.com/exchange/events/Enabled", _
    "http://schemas.microsoft.com/exchange/events/EventMethod", _
    "http://schemas.microsoft.com/exchange/events/MatchScope", _
    "http://schemas.microsoft.com/exchange/events/Priority", _
    "http://schemas.microsoft.com/exchange/events/ScriptUrl", _
    "http://schemas.microsoft.com/exchange/events/SinkClass", _
    "http://schemas.microsoft.com/exchange/events/TimerExpiryTime", _
    "http://schemas.microsoft.com/exchange/events/TimerInterval", _
    "http://schemas.microsoft.com/exchange/events/TimerStartTime")

  ' Specify the event folder and the event registration name
  strParentFolder = "file://./backofficestorage/" + _
                     Server + "/mbx/user1/inbox"

  strEventRegistrationName = "evtreg1"  'If you want to enum all the events, then leave this blank

  'Build the sql query to get the events
  'This section gets all event types so that you don't have to change this per event type
  'To limit the event types, remove the unwanted event types from aPropNames
  Dim i

  Query = "SELECT "
  For i = LBound(aPropNames) To UBound(aPropNames)
    Query = Query + Chr(34) + aPropNames(i) + Chr(34)
    If i <> UBound(aPropNames) Then
      Query = Query + ", "
    End If
  Next
  Query = Query + " FROM SCOPE('shallow traversal of " + Chr(34) + strParentFolder + Chr(34) + "')"
  Query = Query + " WHERE " + Chr(34) + "DAV:contentclass" + Chr(34) + " = 'urn:content-class:storeeventreg'"
  If strEventRegistrationName <> "" Then
    'event folder name specified
    Query = Query + " AND " + Chr(34) + "DAV:displayname" + Chr(34) + " = '" + strEventRegistrationName + "'"
  End If

  Dim rec As New ADODB.Record
  rec.Open strParentFolder  'root binder will select the correct provider
  If Err.Number <> 0 Then
    Debug.Print "Error Executing Query : " & Err.Number & " " & Err.Description & vbCrLf
    Exit Sub
  End If

  rs.Open Query, rec.ActiveConnection
  If Err.Number <> 0 Then
    Debug.Print "Error Executing Query : " & Err.Number & " " & Err.Description & vbCrLf
    Exit Sub
  End If

  ' Go thru each entry in the recordset
  Do While (rs.BOF <> True And rs.EOF <> True)
    For Each fld In rs.Fields
      If fld.Value <> vbNull Then
        Debug.Print fld.Name & ", " & fld.Value & vbCrLf
      End If
    Next
    Debug.Print "***********************************************" & vbCrLf
    rs.MoveNext
    If Err.Number <> 0 Then
      Debug.Print "Error Moving To Next Record : " & Err.Number & " " & Err.Description & vbCrLf
      Exit Sub
    End If
  Loop

  Set rs = Nothing

End Sub

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Managing Event Registrations with RegEvent.vbs

This topic covers the following information:

Registering for an Asychronous Event

Registering for an OnSyncSave Event

Registering for a System Event

Registering for an OnTimer Event

Deleting Event Registrations

Enumerating Event Registrations

You can manage event sinks by using the Microsoft® Visual Basic® script RegEvent.vbs. For more information, see The RegEvent Script.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Registering for an Asynchronous Event

The following example uses the RegEvent script to register for an OnSave event and an OnDelete event.

Example

cscript RegEvent.vbs add "onsave;ondelete" Exoledb.ScriptEventSink.1
   file://./backofficestorage/exchange.microsoft.com/user1/inbox/EventRegItem1
   -m deep -file d:\test.vbs

Related Topics

  • Event Registration

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Registering for an OnSyncSave Event

The following example uses the RegEvent script to register for an OnSyncSave event.

Example

cscript RegEvent.vbs Add OnSyncSave ExOleDB.ScriptEventSink.1
   file://./backofficestorage/mydomain.com/user1/inbox/EventRegItem5
   -file c:\script3.vbs

Related Topics

  • Event Registration

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Registering for a System Event

The following example uses the RegEvent script to register for an OnMdbStartup system event. The command specifies the script host sink class (ExOleDB.ScriptEventSink.1), which then runs the script specified with the -url option.

Example

cscript RegEvent.vbs add onmdbstartup ExOleDB.ScriptEventSink.1
   http://mystore/public/myfolder/startupevent
   -url http://mystore/myeventscripts/script.vbs

Related Topics

  • Registering for an OnTimer Event

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Registering for an OnTimer Event

The following example uses the RegEvent script to register for an OnTimer event.

Timers have scope, in the same way as other events. With timers, however, no event occurs in that location to cause the specified event to occur (such as a save event or a delete event). Note that scope does define a specific location for the registration event item, which can affect the security context of the event sink, and guarantees that the event will be deleted if the folder containing the timer event registration is deleted.

For more information about registering and managing event registrations, see Event Registration.

Examples

Add an OnTimer event to occur every minute for one hour:

cscript RegEvent.vbs add ontimer sink1.sink1.1
   file://./backofficestorage/mydomain/public%20folders/events/EventRegTimerItem1
   "8/4/98 01:50:00 AM" 1 -e "8/4/98 02:50:00 AM"

Register for an event handled by a script:

cscript RegEvent.vbs add ontimer ExOleDB.ScriptEventSink.1
   file://./backofficestorage/mydomain/mbx/user1/inbox/TimerEventReg2
   "09/15/98 02:35:00 PM" 1  -e "09/15/98 03:35:00 PM"
   -url http://public.microsoft.com/my_script_location/script2.vbs

Related Topics

  • Event Registration

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Deleting Event Registrations

You can use the RegEvent script to delete event registrations.

Remarks

RegEvent does not recursively delete events in child folders.

Examples

'delete an item via its URL
cscript RegEvent.vbs delete file://./backofficestorage/exchange.microsoft.com/mbx/user1/inbox/evtreg1

'delete all items in a folder via the folder's URL
cscript RegEvent.vbs delete file://./backofficestorage/exchange.microsoft.com/mbx/user1/inbox all

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Enumerating Event Registrations

You can use the RegEvent script to enumerate event registrations. The enumeration includes a list of properties for each registration item.

Remarks

RegEvent does not recursively enumerate events in child folders.

Examples

`Enum an event by specifying an item URL
cscript RegEvent.vbs enum
   file://./backofficestorage/exchange.microsoft.com/mbx/user1/inbox/evtreg1

`Enumerate events in a folder by specifying a folder URL
cscript Regevent.vbs enum
   file://./backofficestorage/exchange.microsoft.com/mbx/user1/inbox all

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Development Environment

The following sections describe how to set up an environment for developing applications for Microsoft® Exchange 2000 Server. They also present information about Microsoft® Internet Explorer 5 and Active Server Pages (ASP) to help you get started quickly.

Read these topics for information about:

Web Development Tools

Programming Languages

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Web Development Tools

This section discusses the various Web development tools and technologies that you can use to build Web-based collaboration solutions with Microsoft® Exchange 2000 Server. The following sections cover:

Working with Internet Explorer 5

Working with ASP Applications

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Working with Internet Explorer 5

Microsoft® Internet Explorer 5 and later enables you to fully utilize the Extensible Markup Language (XML) and browser development tools in Microsoft® Exchange 2000 Server. Internet Explorer 5 renders XML data and supports the behaviors and design time controls that are provided with Exchange 2000 Server.

The Web Storage System is an ideal repository for XML documents, Extensible Style Language (XSL) documents, and the HTML files that manipulate them. You can also use HTML documents that contain XML data islands. Your files and scripting can utilize the full capabilities of Internet Explorer 5, including XSL, Dynamic HTML (DHTML), and the XML Document Object Model (DOM).

You can use the new XMLHTTPRequest object to access data in the Web Storage System using the World Wide Web Distributed Authoring and Versioning (WebDAV) protocol. This object enables you to natively create and parse the XML-formatted bodies necessary for WebDAV protocol requests and responses by using the XML DOMDocument object.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Working with ASP Applications

The various Component Object Model (COM) components, such as Microsoft® ActiveX® Data Objects (ADO) 2.5 and CDO for Exchange 2000 Server (CDOEX) provide extensive libraries of constants in their associated type libraries. Using the new Microsoft Internet Information Services (IIS) Web page keyword METADATA, you can easily import these constants into your Active Server Pages (ASP) applications and make them globally available when you write scripts.

Note In Microsoft® Exchange System Manager: Turn on Script Execute Permissions for ASP and Scripts and Executables for Internet Server Application Programming Interface (ISAPI) filters. Otherwise, you will get a 403 Permission Denied error.

To import these constants, you place a METADATA directive, such as the following, at the top of your ASP file or in your GLOBAL.ASA file:

<!--METADATA TYPE="typelib" UUID="CD000000-8B95-11D1-82DB-00C04FB1625D" NAME="CDO for Exchange 2000 Type Library" -->
<!--METADATA TYPE="typelib" UUID="CD001000-8B95-11D1-82DB-00C04FB1625D" NAME="Microsoft CDO Workflow Objects for Microsoft Exchange"-->
<!--METADATA TYPE="typelib" UUID="25150F00-5734-11D2-A593-00C04F990D8A" NAME="Microsoft CDO for Exchange Management Library"-->
<!--METADATA TYPE="typelib" UUID="00000205-0000-0010-8000-00AA006D2EA4" NAME="ADODB Type Library" -->

This METADATA directive has the effect of importing the type information into the page at run time, so you can use module constant names in your scripts without having to define them beforehand.

Example

<!--METADATA TYPE="typelib" UUID="CD000000-8B95-11D1-82DB-00C04FB1625D" NAME="Microsoft CDO for Exchange 2000 Library" -->
<!--METADATA TYPE="typelib" UUID="CD001000-8B95-11D1-82DB-00C04FB1625D" NAME="Microsoft CDO Workflow Objects for Microsoft Exchange"-->
<!--METADATA TYPE="typelib" UUID="25150F00-5734-11D2-A593-00C04F990D8A" NAME="Microsoft CDO for Exchange Management Library"-->
<!--METADATA TYPE="typelib" UUID="00000205-0000-0010-8000-00AA006D2EA4" NAME="ADODB Type Library" -->
<HTML>
 <BODY>
  <H1>Test the METADATA Directive Page</H1>
  <p>Here are some of the field name string constants within CDOEX type library :</p>

  <H4>Some CDO for Exchange 2000 Server String Constants</H4>
  <TABLE>
   <TR><TD><b>cdoTo</b>   </TD><TD><%=cdoTo%>    </TD></TR>
   <TR><TD><b>cdoFrom</b> </TD><TD><%=cdoFrom%>  </TD></TR>
   <TR><TD><b>cdoUTF_8</b></TD><TD><%=cdoUTF_8%></TD></TR>
  </TABLE>

  <H4>Some CDO for Exchange Enumeration Constants</H4>
  <TABLE>
   <TR><TD><b>cdoSendUsingPickup</b></TD><TD><%=cdoSendUsingPickup%>  </TD></TR>
   <TR><TD><b>cdoSendUsingPort</b></TD><TD><%=cdoSendUsingPort%></TD></TR>
  </TABLE>

  <H4>Some ADO Enumeration Constants</H4>
  <TABLE>
   <TR><TD><b>adReadAll</b>    </TD><TD><%=adReadAll%>    </TD></TR>
   <TR><TD><b>adReadLine</b>   </TD><TD><%=adReadLine%>   </TD></TR>
   <TR><TD><b>adTypeBinary</b> </TD><TD><%=adTypeBinary%> </TD></TR>
   <TR><TD><b>adTypeText</b>   </TD><TD><%=adTypeText%>   </TD></TR>
  </TABLE>

 </BODY>
</HTML>

To add type information from other type libraries, simply add another METADATA directive to the ASP file.

Putting these directives in your GLOBAL.ASA file makes all these constants available across the current ASP application.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Programming Languages

This section describes how to use various programming languages when you build collaborative applications using Microsoft® Exchange 2000 Server. Each topic describes how to set up the development environment for use with the language. Additional topics provide useful information about using that language effectively when developing applications.

The following sections cover:

Working with C

Working with C++

Working with Visual Basic

Working with VBScript

Working with Windows Scripting Host

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Working with C

Writing applications for Microsoft® Exchange in C is quite similar to doing so in C++. The various header files required are the same as those required with C++. These headers are generated by the MIDL.exe tool, which automatically builds special C functions that simplify working with the interface v-table structures that the Component Object Model (COM) specification requires. C++ supports these constructs natively.

The C programming language does not support symbol namespaces, unlike C++. If your applications use both Collaboration Data Objects (CDO) and MAPI, you may experience duplicate symbol errors during compilation. Read the following section for more information:

Using CDO and MAPI in the Same Modules

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Using CDO and MAPI in the Same Modules

The C programming language does not support a namespace mechanism. Therefore, all linkage symbols for a particular executable or dynamic-link library (DLL) must be unique; if they are not, the linker will raise an error at link time. You must make sure that type names used in various headers are not the same; if they are, you must perform a little compiler magic to make things work.

One such name class occurs if you attempt to write a C program that uses both MAPI and CDO for Exchange 2000 Server (CDOEX). The MAPI header file mapidefs.h and the CDOEX header file cdoex.h both contain a definition for an interface called IMessage. Of course, the MAPI IMessage interface is quite different from the definition for CDOEX. If you must write C code that uses both MAPI and CDOEX in the same module, you need to re-map names as shown in the following example:

#define IMessage ICDOMessage
#define IMessageVtbl ICDOMessageVtbl
#define IID_IMessage IID_ICDOMessage
#include "cdoex.h"
#include "cdoex_i.c"

#undef IID_IMessage
#undef IMessageVtbl
#undef IMessage

#include "mapidefs.h"
#include "mapiguid.h"

Then, when you refer to the CDO IMessage interface, you must refer to it as ICDOMessage and refer to its IID as IID_ICDOMessage, as shown in the following example:

#pragma comment(lib,"uuid.lib")
#pragma comment(lib,"ole32.lib")
#pragma comment(lib,"oleaut32.lib")

int main() {

  MAPIInitialize(...);

 ICDOMessage* pMsg = NULL;
 HRESULT hr = CoCreateInstance(
     CLSID_Message,
     NULL,
     CLSCTX_INPROC_SERVER,
     IID_ICDOMessage,
     (void**)&pMsg
     );

 MAPILogonEx(...); // for brevity
 // ...
 MAPIUninitialize();
}

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Working with C++

The technologies used to build applications with Microsoft® Exchange, such as CDO and Microsoft® ActiveX® Data Objects (ADO), are Component Object Model (COM) components, which provide their services through the COM run time. To start working immediately in a C++ development environment, you simply need to include the appropriate type information (interfaces and enumerations) and GUIDs. In most cases, header files that contain this type information are provided in the Platform SDK section of the MSDN® Library. In addition, most COM components have an associated type library contained as a resource in the dynamic-link library (DLL) that can be used to extract type information (although in Active Directory™ Service Interfaces (ADSI), the type library is in a separate file). The names and locations of these files are discussed in the following sections.

C++ provides the greatest amount of flexibility and speed when you build applications. Besides CDO and ADO, you can use native OLE DB and C++-compatible ADSI interfaces and functions in your applications.

The following sections discuss:

Using C++ Header Files

Using Native COM Support in C++

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Using C++ Header Files

This section describes the header files you use when you build applications with Microsoft® Exchange.

This section lists each Component Object Model (COM) component (or group of components) and provides a table of header files with a brief description of each.

Microsoft CDO for Microsoft Exchange (CDOEX)

Include file | Description
cdoex.h | Contains type information for Collaboration Data Objects (CDO) COM interfaces, COM classes and enumerations.
cdoex_i.c | Contains the GUIDs (CLSID, IID, LIBID) for CDO.
cdoexstr.h | Contains the string constants used with CDO. These include string constants for Exchange and CDO schema fields.
cdoexerr.h | Contains constant definitions for all the CDO custom (FACILITY_ITF) error codes.
adoint.h* | Contains the Microsoft® ActiveX® Data Objects (ADO) 2.5 Library type definitions. This header is required for CDO to function. It is automatically included in cdoex.h.
adoid.ic* | Contains GUIDs for ADO interfaces and COM classes.

* The adoint.h header is included automatically in the cdoex.h header file. The adoid.ic source file, however, is not.

Microsoft CDO Workflow Objects for Microsoft Exchange (CDOWF)

See Using Native COM Support in Microsoft Visual C++ for using workflow classes in C++.

Component file | Description
cdowf.dll | Contains the type library for the CDO Workflow COM interfaces, COM classes, and enumerations.

Microsoft CDO Management Objects for Microsoft Exchange (CDOEXM)

Include file | Description
cdoexm.h | Contains type information for CDO for Exchange Management (CDOEXM) COM classes, interfaces, and enumerations.
cdoexm_i.c | Contains GUID definitions for CDOEXM types.

Note CDO types and ADO types integrate at the interface level. This means that type information supplied by the ADO interface definitions must be present for CDO to work properly. The cdoex.h header file includes a reference to the ADO header file adoint.h. This header file corresponds to the Microsoft ADO 2.5 Library and should be present in the include path. If you plan to create ADO objects directly, you will also need the file adoid.ic. This file contains the GUIDs for ADO COM classes and interfaces.

Microsoft Active Directory Services Interfaces (ADSI)

Include file | Description
activeds.h | Contains type information for Active Directory™ Service Interfaces (ADSI) COM classes, interfaces, and enumerations. Also contains functions and interfaces useful to C++ programmers. See the ADSI documentation for more information.

OLE DB 2.5 Headers

Include File | Description
oledb.h | Contains type information for OLE DB COM classes, interfaces, and enumerations. Also contains functions and interfaces useful to C++ programmers. See the OLE DB 2.5 documentation for more information.
oledberr.h | Contains error constants used when programming with OLE DB interfaces. See the OLE DB 2.5 documentation for more information.

Note When working in C++, you can take advantage of exposed OLE DB interfaces on CDO and ADO objects. If you plan to do so, you should include the OLE DB headers listed in the preceding table. These interfaces, however, are not required.

Increased Build Performance

In many cases, the use of the using namespace XXX directive significantly reduces the resolution tasks required by the compiler; this decreases build times significantly.

#include "cdoex.h"
#include "cdoex_i.c"
using namespace CDO;
...code...

If you define CDO_NO_NAMESPACE before you include a CDO header file, the CDO namespace is removed from the type information, as shown in the following example:

#define CDO_NO_NAMESPACE
#include "cdoex.h"
#include "cdoex_i.c"
...code...

Type Conflicts and Namespace Resolution

When coding in C++ you can include other type declarations that conflict with CDO types. For example, mapidefs.h contains an IMessage type, which produces an error when you attempt to program using both cdoex.h and mapidefs.h. The solution to such conflicts is to use namespaces and then explicitly reference all redundant types, as in the following example:

#include "cdoex.h"
#include "cdoex_i.c"
#include "mapidefs.h"
...
CDO::IMessage* pCDOMessage;
::IMessage* pMAPIMessage;

Examples

Using the CDO Namespace

In the following example, all CDO types are explicitly prefixed with the CDO C++ namespace:

#include "cdoex.h"
#include "cdoex_i.c"
#include "cdoexstr.h"
#include "cdoexerr.h"

#include "cdoexm.h"
#include "cdoexm_i.c"

void main()
{
  CoInitialize(NULL);
  CDO::IMessage*    pMsg    = NULL;
  CDO::IDataSource* pDsrc   = NULL;

  HRESULT hr = CoCreateInstance(CDO::CLSID_Message,
                               NULL,
                               CLSCTX_INPROC_SERVER,
                               CDO::IID_IMessage,
                               reinterpret_cast<void**>(&pMsg));
  hr = pMsg->QueryInterface(CDO::IID_IDataSource, reinterpret_cast<void**>(&pDsrc));

  CDOEXM::IMailRecipient* pMbrecip  = NULL;
  hr = CoCreateInstance(CDOEXM::CLSID_Mailbox,
                               NULL,
                               CLSCTX_INPROC_SERVER,
                               CDOEXM::IID_IMailRecipient,
                               reinterpret_cast<void**>(&pMbrecip));
//...

  CoUninitialize();

}

Importing the CDO Namespace into the Global Namespace

This example imports the CDO namespace into the default, global namespace with the C++ using namespace directive. In this case, you need not use the CDO:: namespace prefix. However, if other types exist with these names, conflicts can occur. For example, MAPI also defines a type called IMessage and having MAPI headers in the same module causes a conflict. To avoid such conflicts, you should use the CDO namespace.

#include "cdoex.h"
#include "cdoex_i.c"
#include "cdoexstr.h"
#include "cdoexerr.h"
using namespace CDO;

#include "cdowf.h"
#include "cdowf_i.c"
//using namespace CDOWF;

#include "cdoexm.h"
#include "cdoexm_i.c"
//using namespace CDOEXM;

void main()
{
  CoInitialize(NULL);
  IMessage*    pMsg    = NULL;
  IDataSource* pDsrc   = NULL;

  HRESULT hr = CoCreateInstance(CLSID_Message,
                               NULL,
                               CLSCTX_INPROC_SERVER,
                               IID_IMessage,
                               reinterpret_cast<void**>(&pMsg));
  hr = pMsg->QueryInterface(IID_IDataSource, reinterpret_cast<void**>(&pDsrc));

...

  CoUninitialize();

}

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Using Native COM Support in C++

If you use Microsoft® Visual C++® 5.0 or later, you can take advantage of its native Component Object Model (COM) support through the #import statement. Using this directive allows you to automatically "import" the type information contained in the component type library to your project. Usually, the files generated have the same name as the component DLL with the extensions .tlh and .tli. Microsoft® ActiveX® Data Objects (ADO) type information is required, so you need to include it as well. You can also use the #import directive to import this information. The following examples illustrate the use of CDO:

#import "c:\program files\common files\system\ado\msado15.dll" no_namespace raw_interfaces_only
#import "c:\program files\common files\Microsoft Shared\CDO\cdoex.dll" no_namespace raw_interfaces_only
#import "c:\program files\exchsrvr\bin\cdowf.dll" no_namespace raw_interfaces_only
#import "c:\program files\exchsrvr\bin\cdoexm.dll"   no_namespace raw_interfaces_only

#include "cdoexstr.h"
#include "cdoexerr.h"

void main() {
  CoInitialize(NULL);
  IMessage* pMsg = NULL;
  HRESULT hr =
     CoCreateInstance( __uuidof(Message),
                      NULL,
                      CLSCTX_INPROC_SERVER,
                      __uuidof(IMessage),
                     (void**) &pMsg
                     );
  ...
  CoUninitialize();
}
Note The #import statement defaults to using namespaces if the no_namespace option is not used or if you do not "import" the namespace using the "using" directive in C++. You must have the ADO 2.5 type information in the global namespace or in the CDO namespace; CDO interfaces make use of ADO types in arguments and they are not qualified by using namespaces. If these types are not in the global namespace or in the CDO namespace, many argument types in methods and properties are undefined and cause a compilation error.

The GUID definitions for ADO and CDO types can be retrieved using the __uuidof operator, which is supported by Visual C++. If you want to, you can use #import flags to specify the CLSID_XXX and IID_XXX definitions.

Consider the following issues when using the #import statement:

  • The #import statement does not include in the header file it generates the constant definitions contained in modules in the type library. CDO provides two separate headers that can be included in your project so that these constants are available. These headers are cdoexstr.h and cdoexerr.h. The first contains the field name constants, and the second includes the CDO custom HRESULT error codes. If you do not include these headers, manually insert these values. For example, the messaging field urn:schemas:mailheader:to has an associated constant called cdoTo in the string constant header file.
  • The #import statement strips the default values for arguments when generating the header files. These defaults can be useful when performing routine operations. If you use #import, explicitly specify the defaults. For example:
//IBodyPart* pBp;
hr = pBp->AddBodyPart();
// this works if you have cdosys.h or cdoex.h.
// The C++ definition for AddBodyPart
// is HRESULT AddBodyPart( long index = -1 );
//

// below we assume #import was used
hr = pBp->AddBodyPart(-1);
// you need to specify the default here if you used #import.
// The definition does not contain the default -1.

Using Interface Pointer Wrapper Classes with Import

The raw_interfaces_only flag to #import directive suppresses the creation of "smart pointer" C++ wrapper classes. In many cases, however, these wrappers are quite useful and make working with CDO in C++ very simple. The following example demonstrates how to use the wrapper classes produced by the #import statement:

#import "c:\program files\common files\system\ado\msado15.dll" no_namespace
#import "c:\program files\common files\Microsoft Shared\CDO\cdoex.dll" no_namespace

#include "cdoexstr.h"
#include "cdoexerr.h"

void main() {
  CoInitialize(NULL);
  {
  try {
   IMessagePtr iMsg(__uuidof(Message));
   FieldsPtr Flds;
   Flds = iMsg->Fields;
   Flds->Item[cdoTo]->Value      = _variant_t("someone@microsoft.com");
   Flds->Item[cdoFrom]->Value    = _variant_t("someone@microsoft.com");
   Flds->Item[cdoSubject]->Value = _variant_t("a test");
   Flds->Item[cdoTextDescription]->Value = _variant_t("this is a test");
   Flds->Update();
   iMsg->Send();
  }
  catch( _com_error err) {
   //  ...
 }

  }
  CoUninitialize();
  return 1;
}

Using the CDO Namespace

You can use namespaces with the #import statement. However, when you import the ADO type information, you must make sure to add it to the CDO namespace or suppress the namespace by adding it to the global namespace. If you do not do this, all ADO type information will reside in the ADODB namespace by default, and CDO arguments that are ADO types will not resolve when you compile. The following example demonstrates this:

#import "c:\program files\common files\system\ado\msado15.dll" rename("ADODB","CDO")
#import "c:\program files\common files\microsoft shared\cdo\cdoex.dll"
#import "c:\program files\exchsrvr\bin\cdowf.dll"
#import "c:\program files\exchsrvr\bin\cdoexm.dll"

#include "cdoexstr.h"
#include "cdoexerr.h"

void main() {
  CoInitialize(NULL);
  {
  try {
   CDO::IMessagePtr iMsg(__uuidof(CDO::Message));
   CDO::FieldsPtr Flds;
   Flds = iMsg->Fields;
   Flds->Item[cdoTo]->Value      = _variant_t("someone@microsoft.com");
   Flds->Item[cdoFrom]->Value    = _variant_t("someone@microsoft.com");
   Flds->Item[cdoSubject]->Value = _variant_t("a test");
   Flds->Item[cdoTextDescription]->Value = _variant_t("this is a test");
   Flds->Update();
   iMsg->Send();
  }
  catch( _com_error err) {
   //  ...
  }
  try {
    CDOEXM::IMailRecipientPtr pMbxRecip(__uuidof(CDOEXM::Mailbox));
    CDOEXM::IMailboxPtr pMbox;
    pMbox = pMbxRecip;
    // ...
  }
catch( _com_error err) {
  //...
}

  }
  CoUninitialize();
  return 1;
}

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Working with Visual Basic

To start working immediately in a Microsoft® Visual Basic® development environment, you only need to add references to the appropriate type libraries. The type libraries are required by Visual Basic to perform v-table binding and marshaling of arguments when required.

For a list of type library names to add to your project, see Adding References to Appropriate Type Libraries.

For a general overview of how to use Visual Basic with CDO for Exchange 2000 Server (CDOEX), see Navigating CDO Interfaces with Visual Basic.

Related Topics

  • Where Do I Use Visual Basic?
  • Adding References to Appropriate Type Libraries
  • Navigating CDO Interfaces with Visual Basic

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Where Do I Use Visual Basic?

Use Microsoft® Visual Basic® to create the following server-side application components:

  • Microsoft Web Storage System Event Sinks

    As part of a large Web-based collaborative application using Microsoft® Exchange 2000 Server, you can build Web Storage System event sinks. These sinks can intercept save and delete events for items in your application's folder, either synchronously or asynchronously.

  • Active Server Pages (ASP) Page COM+ Components

    To increase performance, you can create Component Object Model (COM) components in Visual Basic that are called in ASP script code in an Exchange 2000 Server Web-based folder application. Such a component could use the ASP and CDO for Exchange 2000 Server (CDOEX) COM components to interact with Exchange public and private stores, Microsoft® Active Directory™, or other databases.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Adding References to Appropriate Type Libraries

The following table lists the type library names for the various Component Object Model (COM) components that are used to create applications with Microsoft® Exchange 2000 Server in Microsoft® Visual Basic®. The type libraries act essentially as binary header files for these components, providing the type information necessary for the Visual Basic compiler to create instances of the COM classes, perform v-table binding to the COM interfaces on the objects, and resolve enumeration member names. The type libraries also contain various constants that can be used to simplify development with these components.

COM Components Type Library Names

Type library display name | Type library name | COM component | Remarks
Microsoft® ActiveX® Data Objects (ADO) 2.5 Library | ADODB | msado15.dll | All data access to CDO for Exchange 2000 Server (CDOEX) objects, the Exchange store, and Microsoft® Active Directory™ require this ADO library. It should be included in all applications written with CDO.
CDOEX Library | CDO | cdoex.dll | All core messaging, calendaring, and contact management require this component.
CDO Workflow Objects for Exchange Library | CDOWF | cdowf.dll | Include this library if you plan to create workflow applications with Exchange 2000 Server.
CDO for Exchange Management (CDOEXM) Library | CDOEXM | cdoexm.dll | Include this library if you plan to manage Exchange 2000 Server servers and users in your application.
Active Directory™ Service Interfaces (ADSI) | ActiveDs | activeds.dll (activeds.tlb) | Include this library if you plan to access Active Directory using ADSI interfaces directly.
EXOLEDB Internal Type Library | Exoledb | Exoledb.dll | Includes type information useful when you create OLE DB server event sinks using Visual Basic.

To use these type libraries, you must add them as references to your Visual Basic project in the standard way.

The CDOEX is in the %CommonProgramFiles%\Microsoft Shared\cdo\ directory. The CDO Workflow Objects for Exchange 2000 Server and CDOEX COM components are in the Exchange binaries directory, typically the %ProgramFiles%\exchsrvr\bin directory. When the CDOEX component is installed, the CDOEX for Microsoft® Windows® 2000 component is unregistered from the system. The CDOEX COM component is installed in the Exchange binary directory if you selected the Management Services option during Exchange installation.

Active Directory COM component (ActiveDs.dll) and the ADO 2.5 COM component (msado15.dll) are integral parts of the Windows 2000 operating system.

The physical CDO type library name for both CDO for Windows 2000 and CDOEX is listed as "CDO" and the ADO type library is listed as "ADODB."

After you have added the component references to your project, you should be able to view the type information for the corresponding component.

You can also use only the IDispatch interface on CDO, ADO, and ADSI COM objects. In this case, you do not have to set references in your Visual Basic project to the various component type libraries. Instead, you create instances of the various COM classes by using the programmatic identifier with the CreateObject method. When you do this, performance of your application suffers because all access to the object is through the IDispatch interface.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Navigating CDO Interfaces with Visual Basic

Microsoft® Visual Basic® provides a mechanism for navigating interfaces on objects using the Set keyword. When a variable has been dimensioned to a type exported by a referenced type library, Visual Basic automatically calls IUnknown::QueryInterface when the variable is set. This is illustrated in the following two examples:

Dim iMsg as CDO.IMessage
Set iMsg = New CDO.Message ' (QueryInterface)

Dim iDsrc as CDO.IDataSource
Set iDsrc = iMsg  ' (QueryInterface)

In the first case, when setting the variable iMsg to a new instance of the Message Component Object Model (COM) class, Visual Basic calls QueryInterface internally to retrieve the IMessage interface on the object. In the next case, Visual Basic calls QueryInterface to retrieve the IDataSource interface on the object.

Visual Basic works only with interfaces that are Automation-compatible; interfaces that are Automation-compatible are normally marked in the type library with the oleautomation attribute.

Note The distinction between an object and an interface on an object is not apparent using Visual Basic. Most objects expose only one interface that is Automation-compatible, and normally this interface is dual. However, Active Directory™ Service Interfaces (ADSI) and CDO objects expose multiple Automation-compatible interfaces on many objects. Wherever possible, the distinction between interface and object is preserved in this documentation.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Working with VBScript

Microsoft® Visual Basic® Scripting Edition (VBScript) is a scripting language that can only access the functionality of Component Object Model (COM) objects that support the IDispatch interface. Because all type checking is performed at run time, you do not need to include any type information.

For information about working with VBScript in Active Server Pages (ASP) applications, see Working with ASP Applications.

For information about using the CDO objects and interfaces with VBScript, read Navigating CDO Interfaces with VBScript.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Navigating CDO Interfaces with VBScript

Unlike the Microsoft® ActiveX® Data Objects (ADO) and Active Directory™ Service Interfaces (ADSI) object models, the Collaboration Data Objects (CDO) component provides a consistent interface-driven object model for all programming languages.

For example, most ADSI objects expose multiple interfaces to clients that can bind directly to Component Object Model (COM) interfaces. However, for Automation clients such as scripting languages, each object exposes a single implementation of the IDispatch interface that is adjusted to include all methods and properties on all Automation interfaces on the object.

With CDO, however, the notion of the interface is preserved, and therefore you must navigate to the interface that exposes the functionality you require. Microsoft® Visual Basic® Scripting Edition (VBScript) provides no inherent mechanism for interface navigation, so CDO COM interfaces have been designed to provide this mechanism. Many CDO interfaces provide an implementation of the GetInterface method. This method takes a string identifying the desired interface and returns that interface, if it is exposed. The method acts as an IUnknown::QueryInterface on the object for use by languages that do not support interface navigation. One very common example is the CDO IMessage interface. Objects that expose the IMessage interface normally also expose the IDataSource and IBodyPart interfaces as well. You can use IMessage::GetInterface to navigate to these interfaces by using scripting languages (or anytime you can access the object only through the IDispatch interface).

Dim iMsg
Set iMsg = CreateObject("CDO.Message")
Dim iDsrc
Set iDsrc = iMsg.GetInterface("IDataSource")
Dim iBp
Set iBp = iMsg.GetInterface("IBodyPart")

...

Many CDO interfaces also expose properties that return interfaces on the same object. Using the IMessage interface example again, the IDataSource and IBodyPart interfaces are accessible using the IMessage::DataSource and IMessage::BodyPart properties, as shown in the following code:

Dim iMsg
Set iMsg = CreateObject("CDO.Message")
Dim iDsrc
Set iDsrc = iMsg.DataSource
Dim iBp
Set iBp = iMsg.BodyPart
...

In this case, you can use either the corresponding property on the interface or the GetInterface method to navigate these interfaces.

You cannot access interfaces on objects that are not Automation-compatible. For example, to allow C++ programmers access to raw OLE DB interfaces for items, instances of the CDO Message COM class expose the OLE DB IRow interface. This interface cannot be used by scripting languages and therefore is never returned by a property on an interface or through GetInterface. It is, of course, accessible through QueryInterface.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Working with Windows Scripting Host

To import type library constants into your Microsoft® Windows® Scripting Host applications, add a <reference> element for each type library. To import an entire type library, you only need to specify the programmatic identifier of a COM class in the type library in the object attribute for the <reference> element. The following illustrates how a <reference> element is displayed for each type library.

<Job id="MyJob1">
<reference object="ADODB.Record"/> ' ADODB Type Library
<reference object="CDO.Message"/>  ' Microsoft CDO for Exchange 2000 Library
<reference object="CDOWF.ProcessInstance"/> ' Microsoft CDO Workflow Objects for Microsoft Exchange Library
<reference object="CDOEXM.FolderTree"/>  ' Microsoft CDO for Exchange Management Library

<script language="VBScript" src="X.vbs"/>
</Job>

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Building Solutions on the Web Storage System

The following sections demonstrate how to effectively use the various components of Microsoft® Exchange 2000 Server, such as the Web Storage System, messaging, calendaring, workflow, and so on, to programmatically perform tasks.

Working with E-mail Messaging

Creating Calendaring Applications

Managing Exchange 2000 Server Programmatically

Building Web Storage System Forms

Building Applications That Manage Workflow

Creating Contact Applications

Building Real-Time Collaboration Applications:

Delivering Instant Messages

Developing a Conference Technology Provider

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Working with E-mail Messaging

Microsoft® Exchange 2000 Server provides a powerful platform for users to send messages by using a variety of tools with Exchange 2000 Server, including World Wide Web Distributed Authoring and Versioning (WebDAV), the Web Storage System OLE DB provider, Simple Mail Transport Protocol (SMTP), Network News Transport Protocol (NNTP), Internet Message Access Protocol (IMAP) protocols, and through MAPI. Users receive messages in their private mailbox folders in the Web Storage System, which can be accessed using WebDAV, Post Office Protocol version 3 (POP3), IMAP, and MAPI.

The topics in this section describe how to work with e-mail messages.

Frequently Asked Questions

Introduction

Before You Start

Concepts and Architecture

Programming Tasks

Example Code

Related Topics

Appendixes

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Frequently Asked Questions

This topic covers the most frequently asked questions about programming with Microsoft® Exchange 2000 Server.

Messaging and CDO for Exchange

  • What's the difference between the IBodyPart.BodyParts collection and the IMessage.Attachments collection on a Message object?

  • Why can't I write text to the Stream object of a newly added BodyPart object?

  • How do I set message headers on Message or BodyPart objects when there aren't properties for them?

  • How can CDO objects expose multiple dual interfaces?

What's the difference between the IBodyPart.BodyParts collection and the IMessage.Attachments collection on a Message object?

Although both the IBodyPart.BodyParts and IMessage.Attachments properties return IBodyParts interfaces on collection objects, the objects contained within each collection normally differ. For messages that are encoded as Multipurpose Internet Mail Extensions (MIME), a good rule of thumb is that all body parts with content-disposition set to "attachment" are returned in the IMessage.Attachments collection. Depending on the complexity of the MIME structure, these body parts can exist deep in the body part hierarchy. The IBodyPart.BodyParts collection, on the other hand, contains only that object's immediate child BodyPart objects.

For example, a common MIME structure is expressed in the diagram below as a BodyPart hierarchy below the Message object, labeled A. Each object is designated with a letter; appropriate mail header fields are listed in each box representing an object:

A <--- content-type="multipart/mixed"
  B <--- content-type="multipart/related"
    C <--- content-type="text/plain"
    D <--- content-type="text/html"
  E <--- content-disposition="attachment"
  F <--- content-disposition="attachment"

Object A is the Message object, which is the root of the hierarchy. All other objects are BodyPart objects. The IMessage.Attachments collection for the Message object would contain BodyPart objects E and F. For each object, its IBodyPart.BodyParts collections would contain only the direct descendants of the object in the hierarchy (remember that instances of the Message COM class expose the IBodyPart interface as well as instances of the BodyPart COM class). For object A (the Message object), this would include objects B, E and F. For object B (a BodyPart object), the collection would contain objects C and D. Objects E and F have empty BodyParts collections because they do not have descendants.

For Unix-to-Unix encode (UUENCODE) formatted messages, the hierarchy is only one level deep, because all body parts are necessarily deemed attachments. In this case, only the Message object has descendants, and the IMessage.Attachments and IBodyPart.BodyParts collections are the same. For example,

A
  B <-- UUENCODE attachment
  C <-- ditto
  D <-- ditto

Why can't I write text to the Stream object of a newly added BodyPart object using _Stream::WriteText?

Microsoft® ActiveX® Data Objects (ADO) Stream objects are always one of two types: text or binary. When you first add a BodyPart object to a Message object's body part hierarchy, the content media type defaults to application/octet-stream, rendering a binary decoded content stream (this only applies to the decoded content stream, as the encoded content stream is, by definition, text). The _Stream.WriteText method fails because this method is defined to function only on streams that are of the text type.

To use the WriteText method, you have to set stream type to text. You can do this in one of two ways:

  • Before retrieving the decoded content stream, set the BodyPart object's content media type to a text-based type, such as "text/plain." You can use either the IBodyPart.ContentMediaType property or the urn:schemas:mailheader:content-type field in the IBodyPart.Fields collection. Once set, the returned content stream will be of the text type.
  • Manually change the stream type using the _Stream.Type property on the Stream object. Note that in most cases, you will also need to set the content media type after setting and flushing the stream, as shown in the following examples:

Visual Basic

' EXAMPLE for Step 1
'   Assume that you have a BodyPart object reference in the variable Bp1,
'   and that you wish to add a body part that will hold a text-based
'   content stream.

 Dim Bp2 as IBodyPart
 Dim Strm as ADODB.Stream

 Set Bp2 = Bp1.AddBodyPart
 Bp2.ContentMediaType = "text/plain"

 Set Strm = Bp2.GetDecodedContentStream
 Strm.WriteText "this is the text content here"

 'Commit the changes back
 Strm.Flush

 ' EXAMPLE for 2

 Dim Bp3 as IBodyPart
 Set Bp3        = Bp1.AddBodyPart
 Set Strm       = Bp3.GetDecodedContentStream
 Strm.Type      = adTypeText
 Strm.WriteText "<P>this is some more content</P>"
 Strm.Flush
 Bp3.ContentMediaType = "text/html"
 ' ...

How do I set message headers that are not properties on the IMessage or IBodyPart interfaces?

All message and body part headers can be accessed through an appropriate Fields collection, for example, IMessage.Fields or IBodyPart.Fields. Each mail header resides in the urn:schemas:mailheader: namespace. For example, the Message-ID mail header is identified with the full name urn:schemas:mailheader:message-id.

The fields provided in the urn:schemas:mailheader: namespace are the most common headers defined by the Internet community. However, you can add other headers that are not a part of this default set by adding it to the Fields collection in the urn:schemas:mailheader: namespace. For example, 'urn:schemas:mailheader:Some-Header.'

Dim Msg as New CDO.Message
Dim Flds as ADODB.Fields

Set Flds = Msg.Fields
With Flds
  .Append("urn:schemas:mailheader:message-id") = id
  .Append("urn:schemas:mailheader:custom")   = "some value"
  .Update
End With

How can CDO objects expose multiple dual interfaces?

The short answer is: they can't. By definition, a dual interface is one that both extends the IDispatch interface and provides access to defined methods through the v-table and through the seven methods defined by the IDispatch interface (hence the name dual). Because Component Object Model (COM) uses proxy/stubs to marshal arguments between separate apartments, objects can expose only one IDispatch interface. In addition, you can't trick COM proxy/stubs by returning different addresses depending upon the interface from which you request IDispatch (for more details on this rule, see Advanced ). Therefore, there's one and only one IDispatch interface per object.

This restriction is no problem for languages such as Microsoft® Visual Basic® and Microsoft® Visual J++® that support direct binding to OLE Automation–compatible interfaces. All CDO interfaces use these types, so you can navigate to and use each in the standard way for that language. For example, the CDO Message object exposes the IMessage, IDataSource, and IBodyPart dual interfaces. In Visual Basic, you first add references to the ADO database (ADODB) and CDO type libraries, then type each interface variable using the types in these type libraries, and finally use the Set keyword to navigate to each interface. With J++, use the jactivex tool to create necessary Microsoft virtual machine–compatible Java packages, and then import these packages into their .java source files. The following examples illustrate these procedures:

Visual Basic

Dim iMsg  as CDO.Message
Dim iDsrc as CDO.IDataSource
Dim iBp   as CDO.IBodyPart
Dim iDisp as Object

Set iBp   = New CDO.Message   ' Have IBodyPart
Set iDsrc = iBp               ' Have IDataSource
Set iMsg  = iBp               ' Have IMessage
Set iDisp = iBp               ' Have IDispatch

Visual J++

import cdo.*;

class Main {
  public static void main( String args[] ) {
    IMessage    iMsg  = null;
    IDataSource iDsrc = null;
    IBodyPart   iBp   = null;
    Object      iDisp = null;

    iBp   = (IBodyPart)   new Message(); // IBodyPart
    iDsrc = (IDataSource) iBp;           // IDataSource
    iMsg  = (IMessage)    iBp;           // IMessage
    iDisp = (Object)      iBp;           // IDispatch
    // ...
  }
}

In both cases, you finish with references to all three CDO interfaces and a reference to the IDispatch interface, each on the same object.

The situation is different for scripting languages such as Visual Basic Scripting Edition (VBScript), and Microsoft® JScript®. With these languages, all interactions with COM objects occur through the object's IDispatch interface. Because each object can have only one IDispatch interface, you need separate objects with different implementations of IDispatch, not separate interfaces. Furthermore, you need a way for these languages to access these other objects. To facilitate this, many CDO interfaces define properties and the GetInterface method that return other objects (rather than interfaces) exposing the appropriate IDispatch implementation. However, this produces the illusion of " interface navigation" because it appears to the scriptwriter that the interface itself is being returned. The following code demonstrates this illusion using the CDO Message object:

VBScript

Option Explicit
Dim iMsg
Dim iDsrc
Dim iBp
Set iMsg  = CreateObject("CDO.Message")      ' IMessage    (IDispatch)

Set iDsrc = iMsg.DataSource                  ' IDataSource (IDispatch)
Set iDsrc = iMsg.GetInterface("IDataSource") ' Again IDataSource (IDispatch)

Set iBp   = iMsg.BodyPart                    ' IBodyPart (IDispatch)
Set iBp   = iMsg.GetInterface("IBodyPart")   ' Again IBodyPart (IDispatch)

Visual JScript

var iMsg  = null;
var iBp   = null;
var iDsrc = null;

iMsg  = New ActiveXObject("CDO.Message");  // IMessage (IDispatch)

iBp   = iMsg.BodyPart;                     // IBodyPart (IDispatch)
iBp   = iMsg.GetInterface("IBodyPart");    // Again IBodyPart (IDispatch)

iDsrc = iMsg.DataSource;                   // IDataSource (IDispatch)
iDsrc = iMsg.GetInterface("IDataSource");  // Again IDataSource (IDispatch)

In each case, the script actually interacts with separate objects (object identities), each of which exposes an appropriate implementation of IDispatch; no interface navigation per se is occurring. Instead, object navigation is occurring. The scriptwriter need not be concerned with such details, however; the CDO objects handle all the details internally. Most importantly, the CDO object behaves in the same manner, regardless of which object is used.

Note to C/C++ Programmers (Advanced)

If you write code that depends upon object identity (the physical address of the IUnknown interface), you should be aware of the behavior outlined above. If you use interface properties such as IMessage::get_DataSource or IMessage::get_BodyPart, or if you use the GetInterface method to retrieve interfaces, you're actually getting a different object identity. Consider the following code:

C++, IDL

#include <iostream.h>
#include "cdoex.h"
#include "cdoex_i.c"

void main() {
  CoInitialize(NULL);

  IMessage*    pMsg  = NULL;
  IDataSource* pDsrc = NULL;
  IUnknown*    pUnk  = NULL;
  IUnknown*    pUnk2 = NULL;

  /*
  ** Create an instance of the Message CoClass
  */
  CoCreateInstance(CLSID_Message,
                   NULL,
                   CLSCTX_INPROC_SERVER,
                   IID_IUnknown,
                   (void**)&pUnk);

  /*
  **  have IUnknown (controlling) for Message object
  ** Get the IMessage interface on the object
  */
  pUnk->QueryInterface(IID_IMessage,(void**)&pMsg);

  /*
  ** Get IDataSource interface using property.
  */

  pMsg->get_DataSource(&pDsrc);

  /*
  ** Navigate back to IUnknown interface using new IDataSource prop.
  */

  pDsrc->QueryInterface(IID_IUnknown,(void**)&pUnk2);

  /*
  ** Check if these are the same address
** You know the answer...they're different, but let's
** be scientific about it...
  */

  if(pUnk == pUnk2)
    cout << "pUnk == pUnk2" << endl;
  else
    cout << "pUnk != pUnk2!" << endl;

  pUnk->Release();
  pUnk2->Release();
  pDsrc->Release();
  pMsg->Release();

  CoUninitialize();
}

If you compiled and executed this code, the program would emit

pUnk != pUnk2

In fact, this is the correct behavior; a separate object identity (and hence a different IUnknown address) is returned when an interface is retrieved through a property on the interface or with GetInterface. This time, the IDispatch interface covers the implementation of the requested interface (IDataSource), essentially "shifting" from the previous.

You can think of it this way: Microsoft® Visual C++®, Visual Basic, and J++ can use multiple Automation interfaces on the same object. Scripting languages, however, require an object model with a one-to-one correspondence between object and IDispatch interface. The answer is to provide both: CDO objects conform to both models, exposing multiple Automation-compatible interfaces on the object for use by Visual C++, Visual Basic, and J++, and spawning separate objects (one for each type of interface) to accommodate scripting languages. For each spawned object, the IDispatch implementation covers the functionality of the target dual interface in "round-robin" fashion.

You may wonder why all of this is needed. It may appear at first glance that with a clever enough implementation of the IUnknown methods for each interface, you could trick the client into using separate IDispatch implementations by returning the appropriate interface address through an interface property or GetInterface. However, this only works when the CDO object resides in the same apartment as the caller. If the client calls from a separate COM apartment (or process, or even machine process), COM silently provides a proxy and stub manager to remote the calls. The client is then invoking methods through interfaces aggregated on the proxy object, not directly on the object itself. The proxy rigorously enforces the COM object identity laws and additionally assumes that there is only one address for each interface exposed by the object. Being unaware of the devious attempt to return "appropriate" IDispatch physical addresses in round-robin fashion to the client, it instead preempts us, always returning the first IDispatch address retrieved by the client, and regardless of how this interface is subsequently requested. To circumvent this behavior, we are forced to return interfaces exposed on different object identities (and therefore though different proxy objects) to get the new IDispatch address (through the new proxy object) to the client in the other apartment. The price paid for this approach is one interface (v-table) duplicate for each exposed interface per IDispatch "shift."

It is essential that you understand this behavior if you intend to aggregate CDO interfaces on your objects.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Introduction

Messaging is a platform for users and processes to send and receive electronic messages. In any collaboration application, users and processes need to communicate and coordinate their efforts. Microsoft® Exchange 2000 Server provides a powerful platform for users to send messages by using a variety of tools with Exchange 2000 Server, including World Wide Web Distributed Authoring and Versioning (WebDAV), the Web Storage System OLE DB provider, Simple Mail Transport Protocol (SMTP), Network News Transport Protocol (NNTP), Internet Message Access Protocol (IMAP) protocols, and through MAPI. Users receive messages in their private mailbox folders in the Web Storage System, which can be accessed using WebDAV, Post Office Protocol version 3 (POP3), IMAP, and MAPI. These messages are natively stored in the Internet standard Request for Comments (RFC) 822 and Multipurpose Internet Mail Extensions (MIME) formats.

The Collaboration Data Objects (CDO) for Exchange 2000 Server Component Object Model (COM) component provides a set of COM classes you can use in your application to create, access, modify, and send messages in Internet standard formats. CDO messaging objects can directly bind to messages in the Web Storage System by using the Web Storage System OLE DB Provider, and can send messages using a variety of tools, including SMTP, NNTP, and directly by using the Web Storage System OLE DB Provider.

The following section indroduces the Internet Standard Message Formats supported by the Web Storage System, Exchange 2000 Server, and the CDO for Exchange 2000 Server (CDOEX) COM components:

Internet Standard Message Formats

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Internet Standard Message Formats

The Web Storage System, Microsoft® Exchange 2000 Server, and the CDO for Exchange 2000 Server (CDOEX) Component Object Model (COM) components are designed to support Internet standard message formats that specify how electronic messages should be formatted when transferred over a network. Messages are stored in Internet standard formats in the Web Storage System and transferred in these formats across the network using the Internet standard Simple Mail Transport Protocol (SMTP). When using the CDOEX COM component, you can create applications that automatically construct, send, receive, and interpret messages in these Internet standard formats.

The following Internet standard message format specifications are described in this section:

The RFC 822 Message Format

The UUENCODE Attachment Format

The MIME Message Format

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


The RFC 822 Message Format

The Internet Request for Comments (RFC) 822 specification defines an electronic message format consisting of header fields and an optional message body. The header fields contain information about the message, such as the sender, the recipient, and the subject. If a message body is included, it is separated from the header fields by an empty line (\r\n).

The following example illustrates a message in the RFC 822 message format:

From: someone@microsoft.com
To: someone_else@microsoft.com
Subject: An RFC 822 formatted message

This is the plain text body of the message. Note the blank line
between the header information and the body of the message.

The RFC 822 message format is the basis for other message formats. The following example illustrates the Usenet article/message format specified by RFC 850:

From: someone@<yourcompany>.com
Subject: A basic RFC 850 formatted message
Newsgroups: comp.<yourcompany>.test

The body of this message is plain text. Note the blank line
between the header information and the body of the message.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


The UUENCODE Attachment Format

The Unix-to-Unix encode (UUENCODE) format provided one of the earliest ways to add attachments to messages. In the UUENCODE format, attachments are appended to the message body after being encoded using the UUENCODE algorithm. Each attachment is prefixed with the file name and the encoding end string. Multiple attachments are individually appended in sequence and separated by a blank line. In the UUENCODE attachment format, the message body consists of only two basic parts—the message text and the message attachments.

The following example shows a message body formatted using the UUENCODE attachment format that contains the message text and an attached Microsoft® Word file:

To: "User 1" <user1@microsoft.com>
From: "User 2" <user2@microsoft.com>
Subject: My latest draft.

I've attached my latest draft.
Regards,
User 2

begin 644 mydraft.doc
AAAAAAAAAAFDFAAAAFAFAF....

Although the UUENCODE format provides a way to add attachments to messages, it does not define ways to:

  • Indicate the type of the attachment, except through the file's extension.
  • Specify alternate character encoding for the message text to support international languages.
  • Relate groups of attachments.
  • Indicate that the message text is a form of rich text, such as HTML or Rich Text Format (RTF) formatted text.
  • Provide future enhancements to a structure of complex message bodies. The UUENCODE attachment format is neither flexible nor descriptive.

The next section, The MIME Message Format, describes a message format that enables each of these enhancements.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


The MIME Message Format

The Multipurpose Internet Mail Extensions (MIME) specification enables the exchange of messages with more complex content than Request for Comments (RFC) 822.

The body of a MIME-formatted message is subdivided into body parts. Body parts contain parts of a message—for example an image, a spreadsheet, text formatted using HTML, an alternate representation of the message text, a sound file, or an executable program. The MIME specification also defines additional mail header fields to describe aspects of each message body part. The MIME header fields enable you to do the following:

  • Specify the type of content within the body part, such as an image, an application file, an executable program, and so on.
  • Specify the class of content within the body part. For example, a Microsoft® Word document attachment would be of the type application/msword, but its purpose or class could be an expense report or a specification. Distinct from the type of content, the class defines the intent or purpose of the content.
  • Specify the encoding for each content part when encoding is necessary—for example, in a binary file.
  • Specify a character encoding other than United States (US) ASCII for each separate text body part.
  • Specify the intended disposition of a body part, for example, inline or attachment.
  • Specify a base Uniform Resource Identifier (URI) for resources referenced in HTML content.

Body parts can be organized into groups formed in a hierarchy. With this hierarchy, you can relate multiple body parts in the body of a message. For example, you can indicate that a body part consists of the following:

  • Multiple representations of the same message, such as plain text, HTML, and audio.
  • Multiple parts with related resources that are to be assembled when displayed to the reader. For example an HTML page that consists of HTML, images, style sheets, frames, JavaScript files, and so on.
  • Multiple parts that vary in purpose, some being alternate representations, some attachments, and some groups of related resources.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


MIME Message Body Parts

A message body formatted according to the Multipurpose Internet Mail Extensions (MIME) specification is subdivided into parts that are organized as a hierarchy. As with any hierarchy, some parts contain other parts called descendants, and all parts have ancestors except for the top part, called the root. Each part or subdivision of the body is defined as a body part. Body parts that do not contain other body parts are defined as content body parts, and body parts that do contain other body parts are defined as multipart body parts. The following example shows a hierarchy of parts; located at the top of the hierarchy is the root body part, labeled R. It has direct descendants, labeled A1 and A2.

R
  A1
    A1.1
    A1.2
  A2
    A2.1
    A2.2

The body parts R, A1, and A2 are multipart body parts because they contain descendants; A1.1, A1.2, A2.1, and A2.2 are content body parts because they do not contain descendants. These body parts contain the actual content of the message, such as the plain-text version of the message, an attachment, a HTML page, and so on.

In the MIME formatting scheme, multipart body parts contain only other body parts and do not directly contain the content of the message. Their purpose is to define the relationship of their descendants.

The MIME specification defines the header Content-Type to indicate the type of body part. For example, the body part type indicates what kind of data the body part contains. Values for the Content-Type header contain a primary and secondary type indicator separated by a forward slash (/), for example, image/gif and multipart/related. Multipart body parts always have a primary type of multipart. All non-multipart body parts have some other type of multipart, for example image, application, text, and so on. For additional information, see MIME Extensions to Internet Mail in the appendix.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Content Body Parts

A content body part contains content and header fields, which provide information about the content. The content is any array of bytes, from a binary file to HTML-formatted text. When necessary, the content is encoded so that the entire body of the message complies with the Request for Comments (RFC) 822 specification. The Multipurpose Internet Mail Extensions (MIME) specification defines the Content-Transfer-Encoding header to specify how the body was encoded if encoding was required. Additional information about the body part can be specified using header fields. The Content-Disposition header field is used to indicate whether the content is intended as a message attachment or to be displayed inline with content from other body parts in the message body. The Content-Type header field indicates what type of content is contained in the body part. When the content is text, the header normally indicates the character encoding used in the message.

If you send a message that includes an image called Picture.gif, and the image is an attachment, your e-mail program must encode the image binary data into US-ASCII characters so that the message can be transmitted over the network using the Simple Mail Transport Protocol (SMTP). To correctly decode and display the image, the recipient must know the Content-Type, how it was encoded, and how it should be handled. The headers must convey that:

  • The type of content in the body part is an image in Graphics Interchange Format (GIF) (image/gif).
  • The binary data in the body part was encoded using the base64-encoding algorithm.
  • The body part is intended as an attachment to the message.
  • The suggested file name is Picture.gif.

The following example shows the headers that convey this information to the recipient's e-mail program:

Content-Type: image/gif;
   name="picture.gif"
Content-Transfer-Encoding: base64
Content-Disposition: attachment;
   filename="picture.gif"

[encoded content here]

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Multipart Body Parts

The Multipurpose Internet Mail Extensions (MIME) specification defines several multipart content types that are used to describe the relationship of descendant body parts. For example, when a message contains both a US-ASCII text message and an image attachment, the body is subdivided into three parts: the root body part, the body part containing the US-ASCII message text, and the body part containing the image attachment. The root body part has a Content-Type of multipart/mixed and contains the other two body parts. Therefore, the text and the attachment are descendants of the root body part. These descendant body parts have Content-Type text/plain and Content-Type image/XXX, respectively.

Another example is when alternate representations of a message are present in a message. Each representation is stored in a body part that is a descendant of a body part with Content-Type set to multipart/alternative. This Content-Type value indicates to recipients that the body part contains alternative representations of a single message, for example in US-ASCII text, HTML, and audio.

For more information on body parts, content types, and the MIME specification, see MIME Extensions to Internet Mail in the appendix.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


MIME Hierarchies of Body Parts

A Multipurpose Internet Mail Extensions (MIME)-formatted message is divided into a hierarchy of body parts. Multipart body parts define the relationships between descendant body parts, and content body parts contain the actual content of the message. The illustration below represents a typical MIME hierarchy for a message that contains the following content:

  • Alternative versions of the message, in US-ASCII plain text and HTML
  • A related image used to render the HTML content
  • A Microsoft® Word attachment

Content body parts are displayed in a shaded box labeled Content. Multipart body parts act as structural nodes in the hierarchy and define the relationships among the descendant content body parts.

Multipart/Mixed Structure

The format of a MIME header is specified by Request for Comments (RFC) 2045. For a complete description of the MIME message format, see RFC 2045, RFC 2046, RFC 2047, RFC 2048, and RFC 2049.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Before You Start

This section does not currently contain any topics. Information will be provided here as it becomes available.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Concepts and Architecture

The following topics describe the concepts and architecture for e-mail messaging.

Messaging and the Web Storage System

Messaging with CDO for Exchange 2000 Server

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Messaging and the Web Storage System

The following section introduces the new messaging technology and the related content classes provided by the Web Storage System and Microsoft® Exchange 2000 Server.

  • Messaging Content Classes - The Web Storage System and messaging applications use content classes to define the intent or purpose of an item. A rich set of content classes used with messaging applications is provided, and your applications can extend these classes to define in finer detail the purpose of messaging items present in the Web Storage System.
  • Automatic Message Property Promotion - The Web Storage System automatically sets properties for messaging items from values contained in the saved message stream.
  • The Exchange Mail Submission URI - Each Exchange 2000 Server private information store provides a special Uniform Resource Identifier (URI) for each mailbox that you can use to send messages. Similar to the Simple Mail Transport Protocol (SMTP), you can send messages using this URI with the Exchange OLE DB (ExOLEDB) provider and with the WebDAV protocol.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Messaging Content Classes

The Web Storage System provides a set of content classes to identify items that are messages. The following table lists the content classes along with a brief description of each.

Content class | Description
urn:content-classes:message | The base content class for all messages. This content class defines an item that is a message and a set of properties that describes the item.
urn:content-classes:calendarmessage | Extends the urn:content-classes:message content class and identifies a message that contains meeting requests, appointments, and so on.
urn:content-classes:reportmessage | Extends the urn:content-classes:message content class and identifies a message that is a report. Such messages include Delivery Status Notifications (DSNs) and Mail Disposition Notifications (MDNs).
urn:content-classes:dsn | Extends the urn:content-classes:reportmessage content class and identifies a message that is a DSN.
urn:content-classes:mdn | Extends the urn:content-classes:reportmessage content class and identifies a message that is an MDN.
urn:content-classes:recallmessage | Extends the urn:content-classes:message and identifies a message that is used to recall a previously sent message.
urn:content-classes:recallreport | Extends the urn:content-classes:recallmessage content class and identifies a message that contains a report about a recalled message.

The following illustration shows the hierarchy of these classes:

      |----> recallmessage    -----> recallreport
      |
message----> calendarmessage
      |                    |-------> mdn
      |----> reportmessage
                           |-------> dsn
Note The recallmessage, recallreport, reportmessage, MDN, and DSN content classes identify a refined intent or purpose for items beyond simply being a message; no additional properties are defined for these classes. These content classes are good examples of the practice of using content class to refine the intended purpose of an item in the Web Storage System. Content class definitions do not need to specify additional properties if those defined by the base class are sufficient. In your applications, you can use similarly defined hierarchies of content classes for the same purpose, such as making the intent or purpose of various items more specific. The calendarmessage content class, on the other hand, defines the additional urn:schemas:calendar:method property, which is specific to these types of message items.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Automatic Message Property Promotion

The Web Storage System automatically sets properties for messaging items when the associated stream is saved. You control this behavior through the file name extension of the item. When you create an item with an .eml extension, and write the item's stream, the Web Storage System assumes that the stream is formatted according to the Request for Comments (RFC) 822 and Multipurpose Internet Mail Extensions (MIME) standards. It examines the inbound stream for various messaging-related values, such as mail header fields and message text, and automatically sets these properties for the item. This is referred to as property promotion; the promotion is from data within the stream to properties for the item. The Web Storage System checks the stream for all properties defined by the urn:content-classes:message content class for promotion.

In the following example, you create an item in your inbox with the name mymessage.eml and you also save and commit the following stream to the item in the Web Storage System:

To: "User 1" <user1@microsoft.com>
From: "User 2" <user2@microsoft.com>
Subject: My latest draft.

This is the text portion of the message.

The following table lists the properties for the items after saving the stream.

Property | Value
urn:schemas:mailheader:to | "User 1" <user1@microsoft.com>
urn:schemas:httpmail:to | "User 1" <user1@microsoft.com>
urn:schemas:httpmail:displayto | User 1
urn:schemas:mailheader:from | "User 2" <user2@microsoft.com>
urn:schemas:httpmail:from | "User 2" <user2@microsoft.com>
urn:schemas:httpmail:frome-mail | user2@microsoft.com
urn:schemas:httpmail:fromname | User 2
urn:schemas:mailheader:subject | My latest draft.
urn:schemas:httpmail:subject | My latest draft.
urn:schemas:httpmail:textdescription | This is the text of the message.
urn:schemas:httpmail:date | 10/5/98 11:49 AM
urn:schemas:httpmail:datereceived | 10/5/98 11:52 AM
DAV:contentclass | urn:content-classes:message
urn:schemas:httpmail:hasattachments | False
Note The Web Storage System does not automatically update the stream for the message when the properties are changed using OLE DB or Microsoft® ActiveX® Data Objects (ADO). You must update the stream separately. To avoid updating the stream separately, use the CDO Message object or the CalendarMessage object when you modify existing items in the Web Storage System. These objects automatically ensure that messaging properties and the item stream remain synchronized.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


The Exchange Mail Submission URI

Microsoft® Exchange 2000 Server provides a new process for sending messages using the WebDAV protocol and the Exchange OLE DB (ExOLEDB) provider. You can send messages using a special Uniform Resource Identifier (URI) called the Exchange mail submission URI. A user's mail submission URI is found by retrieving the value of the urn:schemas:httpmail:sendmsg property of the user's private mailbox folder. To send messages using the URI, the sending agent must have the user's credentials or Send On Behalf Of rights for that mailbox.

To send a message, you have the following two options:

  • Write a Request for Comments (RFC) 821 stream to the item's stream. With HTTP, you do this with the PUT protocol command. With the ExOLEDB provider, you retrieve the item's default stream (adDefaultStream in Microsoft® ActiveX® Data Objects (ADO)) and write the message stream to it. The portion of the stream containing the message must be in the format defined by RFC 822 and the Multipurpose Internet Mail Extensions (MIME) specification. The entire stream must contain the RFC 821 Simple Mail Transport Protocol (SMTP) protocol commands listed at the beginning, as shown in the following example:
    MAIL FROM:: "User 1" <user1@fake.microsoft.com>
RCPT TO: "User 2" <user2@fake.microsoft.com>
RCPT TO: "User 3" <user3@fake.microsoft.com>

(Message Stream)

    The SMTP DATA protocol command is not needed and is assumed after the first blank line designated by the first "\r\n\r\n" sequence in the stream.

    When sending a message over HTTP, the sender must be authenticated as either the owner of the mailbox or a user with Send On Behalf Of rights for this mailbox.

  • Write the properties for the message defined for the urn:content-classes:message content class. This is similar to sending messages using MAPI—the Web Storage System automatically generates the message stream for you when you commit the properties to the item. When sending a message using the ExOLEDB provider, the sender must be authenticated as either the owner of the mailbox or a user with Send On Behalf Of rights for this mailbox. When using this process, you cannot add attachments or send a complex MIME-formatted message.

Unlike the user's outbox folder, the mail submission URI is neither a folder nor an item in the user's mailbox. It is a virtual item used only to send messages by using the HTTP protocol or the ExOLEDB provider.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Messaging with CDO for Exchange 2000 Server

You can use the CDO for Exchange 2000 Server (CDOEX) Component Object Model (COM) component provided by Microsoft® Exchange 2000 Server to manage all aspects of message construction and manipulation. Like its predecessor, CDO for Microsoft® Windows® 2000, you can use CDOEX to construct, process, and respond to messages formatted according to the Internet standard Request for Comments (RFC) 822 and Multipurpose Internet Mail Extensions (MIME) specifications. Such formats are the native storage formats for messages in the Web Storage System.

Messages, like other non-folder items in a Web Storage System repository, consist of a stream of data and a set of associated properties defined by the various messaging content classes. Working directly with the properties might satisfy the needs of your application. For example, working with the properties would suffice if you are working with simple messages that contain only United States (US)-ASCII text or HTML and have no attachments. You can use Microsoft® ActiveX® Data Objects (ADO) or OLE DB to create and transmit such messages, leaving the stream construction to Exchange.

In the case of existing messages in the Web Storage System, you can also rely solely on the message item's properties for your application. However, if you need to manipulate or send more complex messages, such as those with attachments or MIME-formatted bodies, you must be able to parse, interpret, or construct the message's associated MIME stream. ADO provides access to the item's properties and stream, but does not provide any facilities for the management of the item's stream. The CDOEX messaging components provide this functionality.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


CDO Messaging COM Interfaces

The CDO for Exchange 2000 Server (CDOEX) Component Object Model (COM) component defines several COM interfaces that are used to construct and manage messages.

  • IBodyPart Interface defines methods and properties that are used to manage a body part of a message.
  • IBodyParts Interface defines a collection interface that is used to manage a collection of body parts.
  • IMessage Interface defines methods and properties that are used to manage a message.

Each of these interfaces is dual. You can use these interfaces with programming languages such as Microsoft® Visual C++®, Microsoft® Visual Basic®, Visual Basic Scripting Edition (VBScript), and Microsoft® JScript®.

The following interfaces are used when constructing Simple Mail Transport Protocol (SMTP) or Network News Transport Protocol (NNTP) transport event sinks using CDOEX:

ISMTPOnArrival Interface

INNTPOnPostEarly Interface

INNTPOnPost Interface

INNTPOnPostFinal Interface

For more information on transport event sinks and CDO, see SMTP/NNTP Transport Event Sinks with CDO.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


CDO Messaging COM Classes

The CDO for Exchange 2000 Server (CDOEX) Component Object Model (COM) component provides the following implementations of the CDOEX COM interfaces discussed in the previous section:

The BodyPart COM Class represents a message body part.

The Message COM Class represents a message.

The CalendarMessage COM Class represents a message containing calendar items.

The CalendarMessage COM class is discussed in detail in the Calendaring section of this documentation.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


CDO BodyPart Object Hierarchies

Message bodies are organized in CDO as hierarchies of BodyPart objects. In Multipurpose Internet Mail Extensions (MIME)-formatted messages, each body part in the hierarchy is a BodyPart object. The root of the hierarchy is either a Message or CalendarMessage object. The following figure illustrates a possible hierarchy.

Example BodyPart Hierarchy

Navigation through the body part hierarchy is facilitated through the IBodyPart.BodyParts collection and the IBodyPart.Parent property on each BodyPart object.

When you need to construct messages using only the Unix-to-Unix encode (UUENCODE) format, you set the IMessage.MIMEFormatted property to false. In this case, the message text and each attachment to the message are contained in a BodyPart object.

Related Topics

  • IMessage.MIMEFormatted
  • IBodyPart.BodyParts
  • IBodyPart.Parent
  • BodyPart COM Class
  • Message COM Class

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Example 1: Alternative Representations of a Message

Many messages are commonly sent with alternative representations of the message text, for example in both HTML and plain text. With Multipurpose Internet Mail Extensions (MIME), you can indicate to the recipient that the message contains these alternative representations of a message. The following illustration shows what the hierarchy of CDO objects for such a message might look like.

Alternative Representation Body Part Hierarchy

The Message object is itself a body part with a content-type equal to "multipart/alternative." Because of this, its content stream is empty. Its IBodyPart.BodyParts collection has two items, which are both BodyPart objects. Each descendant body part has a content stream with the particular alternative representation of the message.

Related Topics

  • IBodyPart.Fields
  • IBodyPart.BodyParts
  • BodyPart COM Class

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Example 2: Alternative with Attachments

If the message in the previous example had attachments, such as an image and a Microsoft® Word file, the hierarchy of objects might look like the representation in the following illustration.

Alternative Representation with Attachments

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Example 3: Alternative with MHTML Formatting

You can send images, style sheets, scripts, and other related materials along with the message to enable clients to properly render the HTML-formatted message. You can do this by using the MIME Encapsulation of Aggregate HTML Documents (MHTML) format. The following illustration shows what the body part hierarchy might look like.

Alternative Representation with MHTML Formatting

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


CDO BodyPart Fields and Streams

Each body part has a set of fields and possibly some content. To access the fields for a body part, you use the Fields Property. To access the content of the body part, you use the GetEncodedContentStream Method and GetDecodedContentStream Method. Each method returns the content in either encoded or decoded format. To access the entire body part Multipurpose Internet Mail Extensions (MIME)-formatted stream, you use the GetStream Method. Each stream is returned in an Microsoft® ActiveX® Data Objects (ADO) Stream object. The following illustration shows the relationship of the Fields Property and the various streams associated with a body part.

Body part fields are not stored directly as fields for the item in the Web Storage System; they are stored in the MIME-formatted message stream. To manipulate the fields for a body part, use a CDO Message object to open the item from the Web Storage System.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


BodyPart Content Streams

Each content BodyPart object contains a content stream that can be requested using IBodyPart.GetDecodedContentStream and IBodyPart.GetEncodedContentStream. The encoding process is defined by the urn:schemas:mailheader:content-transfer-encoding property in the Fields collection. This corresponds to the Content-Transfer-Encoding mail header field defined by the Multipurpose Internet Mail Extensions (MIME) specification.

For example, a body part containing the message in HTML format in a multipart/alternative hierarchy could have the following decoded content stream:

<html><p>Here is a simple <b>message</b>.

A body part containing a binary attachment or file, such as an image or Microsoft® Word document, would contain totally different streams for the encoded and decoded content. For the encoded content stream, the binary stream would be encoded using an algorithm such as base64 and returned as US-ASCII text. For the decoded stream, a raw binary stream is returned. In addition, the Microsoft® ActiveX® Data Objects (ADO) Stream object has a _Stream.Type property that indicates whether the content is binary or text. For text streams, the character set is identified using the _Stream.Charset property. Changes made to the stream can be saved back to the body part using the _Stream.Flush method. In a sense, the Stream object is bound to the body part as if the BodyPart object were its storage location. To manipulate the content of a body part, always use the decoded content stream.

Body parts that have content-type set to multipart do not have an associated content stream in the CDO object model. These body parts exist solely to create the hierarchy and relationships between descendant body parts. Requesting their content streams raises an exception, but all BodyPart objects have a stream.

Related Topics

  • IBodyPart.GetDecodedContentStream Method
  • IBodyPart.GetEncodedContentStream Method
  • BodyPart Streams

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


BodyPart Streams

All BodyPart objects can generate a stream that is the portion of the Multipurpose Internet Mail Extensions (MIME)-formatted message body starting with that BodyPart object in the hierarchy. This stream is different from a content stream, which contains only the raw content for the body part. The MIME stream is returned by the IBodyPart.GetStream method in an Microsoft® ActiveX® Data Objects (ADO) Stream object. When constructed, the MIME stream for the BodyPart object and all descendants are included.

You can use this stream to copy body part hierarchies between different messages. For example, you might build a complex MIME hierarchy and want to copy the entire hierarchy from one message to another. You can generate the stream for that portion of the first message and save it as the stream of a BodyPart object in another message. Once saved, the MIME-formatted data is parsed and the appropriate BodyPart hierarchy is constructed automatically.

To clarify the difference between a body part's content stream and stream, consider the following example, which illustrates a stream for a body part containing the HTML portion of a message:

Content-Type: text/html;
        charset="iso-8859-1"
Content-Transfer-Encoding: 7bit

<html><p>Here is a simple <b>message</b>

The content stream for the body part would be:

<html><p>Here is a simple <b>message</b>.

Another example is a hypothetical multipart/alternative body part stream:

Content-Type: multipart/alternative;
       boundary="----=_NextPart_000_0000_01BED789.F54D7C60"

This is a multi-part message in MIME format.

------=_NextPart_000_0000_01BED789.F54D7C60
Content-Type: text/plain;
        charset="iso-8859-1"
Content-Transfer-Encoding: 7bit

Here is a simple message.
------=_NextPart_000_0000_01BED789.F54D7C60
Content-Type: text/html;
         charset="iso-8859-1"
Content-Transfer-Encoding: 7bit

<html><p>Here is a simple <b>message</b>.
------=_NextPart_000_0000_01BED789.F54D7C60--
Note In this case, the BodyPart object used to generate this MIME stream does not contain content; it only defines the relationship of its descendant BodyPart objects. If you call the IBodyPart.GetDecodedContentStream or IBodyPart.GetEncodedContentStream for this BodyPart object, an exception is raised.

Related Topics

  • IBodyPart.GetStream Method

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


CDO Message Fields and Streams

Message objects, like BodyPart objects, have an associated Fields collection and a method used to generate the message object’s stream. The Fields collection can be retrieved using either the IBodyPart or IMessage interfaces. The Field objects within each Fields collection are identical. The IMessage interface defines the GetStream method that you use to retrieve the content for an entire message.

The set of messaging fields for a message is defined by the urn:content-classes:message content class. When you set message properties using properties on the IMessage interface, many of these fields are generated automatically.

The format of the message stream is controlled using the IMessage.MIMEFormatted property. If IMessage.MIMEFormatted is set to False, only a plain text message is constructed, and all attachments are added using the Unix-to-Unix encode (UUENCODE) format.

Related Topics

  • IMessage.Fields Property
  • IMessage.GetStream Method

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Message Fields

The set of fields stored with the message is defined by the urn:content-classes:message content class. Many fields defined for messaging content classes refer to the same underlying message data, but they return this data as different data types. For example, every message header field for a Message object can be accessed in the urn:schemas:mailheader: namespace, but all are returned as US-ASCII strings, with any non US-ASCII characters encoded by the process defined in Request for Comments (RFC) 1522. Similarly named fields within the urn:schemas:httpmail: namespace return the same information, but in a different data format. In the urn:schemas:httpmail: namespace, field values are decoded and returned as unicode characters. Another example is the http://schemas.microsoft.com/exchange/sensitivity field that returns an enumerated value rather than a string identifying the sensitivity of the message.

When accessing fields in the urn:schemas:mailheader: namespace, the OLE DB type for the majority of fields is DBTYPE_STR. The Microsoft® ActiveX® Data Objects (ADO) Field interface is dual and Automation compatible. Single-byte characters are returned as wide, two-byte (wchar_t) characters. However, encoded characters are not decoded before being returned.

Related Topics

  • urn:schemas:mailheader: Namespace
  • urn:schemas:httpmail: Namespace
  • http://schemas.microsoft.com/exchange/ Namespace

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Message Streams

When you request the message stream by using the IMessage.GetStream method, the CDO Message object internally constructs the stream. The object formats the stream using the process defined by Request for Comments (RFC) 822 and places the output into the Microsoft® ActiveX® Data Objects (ADO) Stream object. If you have set the IMessage.MIMEFormatted property to False, the Message object uses the Unix-to-Unix encode (UUENCODE) attachment format for the stream. Otherwise, the Message object generates the stream using the Multipurpose Internet Mail Extensions (MIME) format. By default, the IMessage.MIMEFormatted property is set to True. Setting this property to False limits the type of data you can send with your message. Use MIME formatting whenever possible.

The following example shows a typical MIME-formatted message generated by CDO for a message having HTML, plain text message, and an attached Extensible Style Language (XSL) style sheet:

Thread-Topic: This is a test
From: "User 1" <user1@microsoft.com>
To: "User 2" <user2@microsoft.com>
Subject: This is a test
MIME-Version: 1.0
Content-Type: multipart/mixed;
        boundary="----=_NextPart_000_0000_01BED78B.61E13E10"
Thread-Index: Ab7Xxg4EDFQD/RrtQVCb0K8odOtcJA
Content-Class: urn:content-classes:message
X-MimeOLE: Produced By Microsoft MimeOLE V5.00.2918.2701

This is a multi-part message in MIME format.

------=_NextPart_000_0000_01BED78B.61E13E10
Content-Type: multipart/alternative;
        boundary="----=_NextPart_001_0001_01BED78B.61E13E10"

------=_NextPart_001_0001_01BED78B.61E13E10
Content-Type: text/plain;
        charset="iso-8859-1"
Content-Transfer-Encoding: 7bit

Here is a simple message.

------=_NextPart_001_0001_01BED78B.61E13E10
Content-Type: text/html;
        charset="iso-8859-1"
Content-Transfer-Encoding: 7bit

<html><p>Here is a simple <b>message</b>.
------=_NextPart_001_0001_01BED78B.61E13E10--

------=_NextPart_000_0000_01BED78B.61E13E10
Content-Type: text/xml;
        name="test.xsl"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
        filename="test.xsl"

<xsl:stylesheet xmlns:xsl=3D"http://www.w3.org/TR/WD-xsl">
<xsl:template>
  <xsl:copy>
      <xsl:apply-templates select=3D"@*"/>
      <xsl:apply-templates select=3D"* | text()"/>
  </xsl:copy></xsl:template><xsl:template =
match=3D"@*"><xsl:copy><xsl:value-of/></xsl:copy></xsl:template>
</xsl:stylesheet>
------=_NextPart_000_0000_01BED78B.61E13E10--

This example was generated using CDO for Exchange 2000 Server (CDOEX). Using the IMessage.GetStream method for a Message object and written to console using the _Stream.ReadText method of the resulting ADO Stream object.

Note For a Message object, the IMessage.GetStream and the IBodyPart.GetStream methods return identical streams.

Related Topics

  • IMessage.GetStream Method
  • IBodyPart.GetStream Method

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Message Stream and Property Synchronization

Unlike many items in the Web Storage System, there is an assumed relationship between a message item's fields and stream. For example, the urn:schemas:mailheader:to property for the message item is normally the same as the value of the To: header field in the Request for Comments (RFC) 822 message stream. When you save items that have an .eml extension, the Web Storage System parses the inbound item stream, extracts the values for the various messaging fields, and automatically sets these fields for you. The stream is therefore always synchronized with the messaging fields for the item.

However, if you open an existing message using a Microsoft® ActiveX® Data Objects (ADO) Record object and change the item's messaging fields directly, the Web Storage System does not re-generate the message stream. In this case, you must update the message stream manually. If you do not update the stream manually, the item's messaging fields no longer reflect the data contained within the stream.

To avoid these difficulties, use the appropriate CDO messaging object to manipulate messages. The CDO Message and CalendarMessage objects automatically synchronize the message fields and the stream when changes are made to either object. Avoid using an ADO Record object to change the messaging fields of an existing message. If you do use a Record object to change an existing message, update its stream rather than its messaging fields. These fields are set automatically when the message stream is saved and parsed.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


CDO Messaging Configuration

The configuration information for CDO top-level objects is stored in an instance of the Configuration COM class. A Configuration object contains information such as the method used to deliver messages, the paths to the pickup directories for Simple Mail Transport Protocol (SMTP) and NNTP servers, a user's mailbox Uniform Resource Identifier (URI), and so forth. When you create a Configuration object, CDO fills in the default configuration information by collecting information from Microsoft Internet Information Services (IIS) for Microsoft® Windows® 2000 and Microsoft® Outlook® Express, provided they are installed on the computer running CDO.

If you do not create a Configuration object, CDO creates one each time you send or post a message. When sending many messages, create a single Configuration object and use it with each Message object to maximize application performance. For example, you can store this object in an Active Server Pages (ASP) Session or Application object, and retrieve it when you need to send a message.

Passwords specified in Outlook Express are not picked in the Configuration object's field collection. These passwords are specified in a dialog box when you select My Server Requires Authentication in Outlook Express. For outbound mail authentication, however, you can provide a write-only password using the sendpassword field on the Configuration object.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Configuration Fields

Configuration information is stored in an Microsoft® ActiveX® Data Objects (ADO) Fields collection in the Configuration object. Most configuration fields reside in the http://schemas.microsoft.com/cdo/configuration/ namespace. The following table provides a list of common configuration fields along with a brief description of each.

Configuration property | Description
activeconnection | An ADO Connection object used to send messages by using the Exchange OLE DB (ExOLEDB) provider. If this object is not specified, a new Connection object is created to send the message. This Connection object is used only when sending messages in Microsoft® Exchange. You control how messages are sent by setting the sendusing and postusing configuration fields.
mailboxurl | Used to specify the Uniform Resource Identifier (URI) to a user's mailbox when sending messages using the ExOLEDB provider. If this property is not specified, the mailbox URI for the user specified in the sendusername or postusername is constructed using data retrieved from Microsoft® Active Directory™.
sendusing | Used to specify whether to send the message using the local Simple Mail Transport Protocol (SMTP) service drop directory, over the network using the SMTP protocol, or by using the Exchange mail submission URI.
postusing | Used to specify whether to post the message using the local NNTP service drop directory, over the network using the NNTP protocol, or by using the Exchange mail submission URI.
sendusername postusername | Specifies the username to use for credentials when sending or posting messages over the network. Additionally, when sending or posting messages using Exchange, these values are used to look up the user's mailbox URI in Active Directory. You can bypass the lookup by setting the mailboxurl property discussed above in the configuration.
sendpassword postpassword | The passwords associated with sendusername/postusername for credentials when sending messages over the network.
smtpserver nntpserver | Used to indicate the Domain Name System (DNS) name of the SMTP or NNTP service host, if messages are sent using the SMTP/ NNTP protocols.
smtpserverport nntpserverport | Used to indicate the transmission control protocol/Internet protocol (TCP/IP) port of the SMTP or NNTP service, if messages are sent using the SMTP/ NNTP protocols. This field is always used in conjunction with smtpserver/nntpserver field.
smtpauthenticate nntpauthenticate | Used to identify the authentication process, if any, when sending or posting messages using the SMTP/ NNTP protocols.
hardlinklist | Contains the URL to public folders in which to post a message when using Exchange. This property is multivalued, but currently only one URL can be specified.
urlproxyserver | Indicates the proxy server and port used to access external network resources.
timezoneid | (urn:schemas:calendar: namespace) Defines the time zone used to format Date (DATE) values returned by the Message object. This property is set using the CdoTimeZoneId enumeration.
languagecode | Determines what locale identifier is used when localizing message response text. This text can automatically be included in the Message object generated by IMessage.Reply, IMessage.ReplyAll, IMessage.Forward, and IMessage.PostReply. This behavior is controlled using the usemessageresponsetext field in the Configuration object.
usemessageresponsetext | Used to control whether or not message response text is added automatically within messages created using the IMessage.Reply, IMessage.ReplyAll, IMessage.Forward, and IMessage.PostReply methods. The response text is localized using the locale identified by the languagecode configuration field.

The CDO component provides string constants (in this case, cdoSMTPServerPort) that you can use in your program to identify properties and avoid typographical errors. By using the constant instead of the actual string, you can also take advantage of the syntax auto-complete function that is included in Microsoft® Visual Studio®.

Related Topics

  • http://schemas.microsoft.com/cdo/configuration/ Namespace
  • urn:schemas:calendar:timezoneid Field

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


CDO Messaging and ADO

CDO for Exchange 2000 Server (CDOEX) integrates with Microsoft® ActiveX® Data Objects (ADO) 2.5 objects to provide a consistent interface for accessing item data in the Web Storage System. CDO objects are similar to ADO objects. Like ADO Record and Recordset objects, the Message, CalendarMessage, BodyPart, and CalendarPart objects expose a Fields collection and a way to access an item's stream. CDO objects facilitate binding to Web Storage System items through the CDO IDataSource interface Open, SaveTo, and SaveToContainer methods.

C++, IDL

The CDO objects listed in the previous section also implement the OLE DB CoType TRow interfaces. You can use this set of interfaces on the CDO object as if it were an instance of an OLE DB Row object. For example, you may write a set of high-performance functions in Microsoft® Visual C++® that operate using a passed IRow interface. If you have a CDO object such as a Message or BodyPart object, it is not necessary to create a separate OLE DB Row object to pass to the function. Instead, you can pass the IRow interface on to the CDO object. If necessary, the function can always determine whether the object is a CDO object by calling QueryInterface for some CDO-specific interface such as IDataSource or IMessage.

The CDO Message and CalendarMessage objects can bind directly to other objects by using the IDataSource.OpenObject and IDataSource.SaveToObject methods. The types of objects you should bind to include the following:

  • ADO Record and Stream objects that are possibly bound to items in the Web Storage System that have a messaging content class. Use the CalendarMessage object to bind objects that have at least the content class urn:content-classes:calendarmessage, or some class derived from this class. Use the Message object to bind objects that have at least the content class urn:content-classes:message or some class derived from this class. You bind the CDO object to these ADO objects using either the _Record or Stream interface.
  • OLE DB Row and Stream objects that are bound to items in the Web Storage System. You bind the CDO object to these OLE DB objects using either the IRow or IStream interface respectively.
  • CDO BodyPart and Item objects. You embed messages by saving them to a BodyPart object in another Message object's BodyPart hierarchy. You bind to these objects using either the IBodyPart or IItem interface, respectively.

An example of binding a CDO object to an ADO or OLE DB object is when you are writing a synchronous Web Storage System event sink. When an event occurs, the sink is passed a reference to an OLE DB/ ADO object containing the triggering item. If the triggering item is a message, you can bind a CDO message object to the object to examine and manipulate it.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


When to Use CDO or ADO for Messaging

You can use both CDO and Microsoft® ActiveX® Data Objects (ADO) objects to send messages. Use the following guidelines to decide when to use CDO or ADO objects in your messaging applications.

Use ADO objects to do the following:

  • Identify items in the Web Storage System that are types of messages.
  • Search folders and folder hierarchies for messages.
  • Set custom properties for messages when the messaging properties are not to be altered.

Use CDO objects to do the following:

  • Create any kind of new message items.
  • Send messages in applications that run on the server.
  • Modify an existing message item, including any associated messaging properties.
  • Synchronize a messaging item's properties and stream if they are out of synchronization.

If you bind an item in the Web Storage System using an ADO object, and later you require use of a CDO Message or CalendarMessage object, bind the CDO object to the ADO object using the IDataSource.OpenObject or IDataSource.SaveToObject methods. You do not need to rebind the CDO object to the item in the Web Storage System to access and modify the item's contents.

In some cases, you must bind a CDO Message object to a Record object. For example, if you create a Web Storage System OnSyncSave event sink, the item causing the event to run is not committed to the Web Storage System when the sink executes. However, the sink passes a reference to an ADO Record object that represents the item in memory. If the item represents a message, create an instance of the Message COM class and bind it to the Record object using the IDataSource.OpenObject method. After you modify the content using the Message object, call IDataSource.Save to commit the changes back to the Record object.

C++, IDL

If you write a Web Storage System event sink using Microsoft® Visual C++®, and you plan to use the OLE DB interfaces rather than the ADO interfaces, you can bind the item using the IDataSource.OpenObject method. Pass the IRow interface to the method to bind the CDO object to the OLE DB Row object housing the item data in memory.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Programming Tasks

The topics in this section describe how to create and manage e-mail messages using Microsoft® Exchange 2000 Server.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Creating a Message

To build a new message, you must first create an instance of the Message Component Object Model (COM) class, as shown in the following example:

Visual Basic

' Reference to Microsoft ActiveX Data Objects 2.5 Library
' Reference to Microsoft CDO for Exchange 2000 Server Library
Dim iMsg as new CDO.Message

C++, IDL

#import "c:\program files\common files\system\ado\msado15.dll" no_namespace
#import "c:\program files\common files\microsoft shared\cdo\cdoex.dll" no_namespace
// ...
MessagePtr iMsg(__uuidof(Message));

VBScript

Dim iMsg
Set iMsg = CreateObject("CDO.Message")

You can create and send or post a simple message by using only the IMessage interface.

  • To send a Simple Mail Transport Protocol (SMTP) message, you must at least set the To and From properties on the IMessage interface.
  • To post an NNTP message, you must at least set the IMessage.Newsgroups and IMessage.Subject properties.
  • To send or post multiple messages efficiently, create a single Message object and reuse it for each message.
  • To send individual messages with the same content to several recipients, change the address and call the IMessage.Send or IMessage.Post method for each message.
  • To send different content in each message, use the IBodyParts.DeleteAll method to clear all of the body parts associated with a Message object.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Configuring the Message Object

To configure a Message object

  1. Create an instance of the Configuration Component Object Model (COM) class.
  2. Populate the configuration settings in the IConfiguration.Fields collection.
  3. Set the IMessage.Configuration property to the IConfiguration object reference on the Configuration object.

Visual Basic

' Reference to Microsoft ActiveX Data Objects 2.5 Library
' Reference to Microsoft CDO for Exchange 2000 Server Library
' ..
Dim iConf As New CDO.Configuration
Dim Flds  As ADODB.Fields
Set Flds = iConf.Fields

' Set the configuration
Flds(cdoSendUsingMethod) = cdoSendUsingPort
Flds(cdoSMTPServer) = "mail.microsoft.com"
' ... other settings
Flds.Update

Dim iMsg As New CDO.Message
Set iMsg.Configuration = iConf

' go on to use Message instance

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Setting Language and Time Zone Information

Language code and time zone information is stored in the Message object's associated Configuration object. These values are stored in the http://schemas.microsoft.com/cdo/configuration/languagecode and urn:schemas:calendar:timezoneid fields.

The language code is used when constructing the response text for reply and forwarded messages. The time zone identifier is used when converting date and time values to local times.

To configure the language code and time zone that are used for messaging, set the http://schemas.microsoft.com/cdo/configuration/languagecode and urn:schemas:calendar:timezoneid fields to appropriate values in the associated Configuration object.

Visual Basic

' Reference to Microsoft ActiveX Data Objects 2.5 Library
' Reference to Microsoft CDO for Exchange 2000 Server Library
' ..
Dim iConf As New CDO.Configuration
Dim Flds  As ADODB.Fields
Set Flds = iConf.Fields

' Set the configuration for Network Send
Flds(cdoLanguageCode) = "en-us"
Flds(cdoTimezoneId) = cdoMountain
' .. set additional fields
Flds.Update

Dim iMsg As New CDO.Message
Set iMsg.Configuration = iConf

Both of these fields have default values that depend on the current computer locale and system settings. In many cases, you will not need to set these values explicitly.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Setting the Send and Post Methods

With the Message object, you have the option of choosing how messages are sent or posted for delivery. These options are determined by the software installed on the computer running your CDO application. The following table lists these methods and describes when the method is available.

Method | Description
Pickup Directory | If the application is running on a computer that has Simple Mail Transport Protocol (SMTP) or NNTP services, you can use the pickup directory for those services.
Network via SMTP or NNTP protocol | You can connect directly to an SMTP or NNTP service and use the SMTP or NNTP protocol to send or post a message.
Microsoft® Exchange | You can send and post messages using Exchange 2000 Server. In this case, the item is submitted by using the Exchange OLE DB (ExOLEDB) provider mail transmission Uniform Resource Identifier (URI) when the sender's mailbox is on a local machine, or through the WebDAV mail transmission URI if the user's mailbox is on a remote Exchange service.

To set the send or post method for messaging objects

  1. Set the http://schemas.microsoft.com/cdo/configuration/sendusing and http://schemas.microsoft.com/cdo/configuration/postusing fields to the desired method in the associated Configuration object. The methods listed in the previous table are identified with CdoSendUsing and CdoPostUsing enumerations.
  2. Set any required or optional configuration fields that correspond to the send or post method.

The required and optional fields depend upon the send or post mechanism.

Visual Basic

' Reference to Microsoft ActiveX Data Objects 2.5 Library
' Reference to Microsoft CDO for Exchange 2000 Server Library
' ..
Dim iConf As New CDO.Configuration
Dim Flds  As ADODB.Fields
Set Flds = iConf.Fields

' Set the configuration for Network Send
Flds(cdoSendUsingMethod) = cdoSendUsingPort
Flds(cdoSMTPServer) = "server.domain.tld"
' .. set additional fields
Flds.Update

Dim iMsg As New CDO.Message
Set iMsg.Configuration = iConf

Related Topics

  • Sending or Posting Using the Network
  • Sending or Posting Using the Pickup Directory

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Sending or Posting Using the Network

To send messages over the network, perform the following steps:

  1. Set the http://schemas.microsoft.com/cdo/configuration/sendusing or http://schemas.microsoft.com/cdo/configuration/postusing field to cdoSendUsingPort or CdoPostUsingPort in the Configuration object.
  2. Set the http://schemas.microsoft.com/cdo/configuration/smtpserver or http://schemas.microsoft.com/cdo/configuration/nntpserver field to a resolvable name (Domain Name System (DNS) or Network Basic Input/Output System (NetBIOS)) for an Simple Mail Transport Protocol (SMTP) or NNTP service on the network.
  3. Set the following additional fields used with network configurations.
    Name | Description
    smtpserverport nntpserverport | The port to use when connecting the service. Defaults are 25 and 119.
    smtpconnectiontimeout nntpconnectiontimeout | The timeout in seconds for attempted connections to the service. Default is 30 seconds.
    smtpaccountname nntpaccountname | The account name.
    smtpauthenticate nntpauthenticate | The mechanism (if any) used to authenticate the service.
    smtpusessl nntpusessl | Indicates whether or not to use Secure Secure Sockets Layer (SSL) for the connection.
    sendusername senduserpassword postusername postpassord | The username and password that are needed to authenticate the Basic Authentication mechanism. These fields are also used when sending mail by using Microsoft® Exchange 2000 Server to look up the user's mailbox Uniform Resource Identifier (URI).

The following example demonstrates how to explicitly set various fields that are used when sending messages over the network.

Visual Basic

' Reference to Microsoft ActiveX Data Objects 2.5 Library
' Reference to Microsoft CDO for Exchange 2000 Server Library
' ..
Dim iConf As New CDO.Configuration
Dim Flds  As ADODB.Fields
Set Flds = iConf.Fields

' Set the configuration for Network Send
Flds(cdoSendUsingMethod) = cdoSendUsingPort
Flds(cdoSMTPServer) = "server.microsoft.com"
Flds(cdoSMTPServerPort) = 25           'standard port for SMTP (default)
Flds(cdoSMTPConnectionTimeout) = 30
Flds(cdoSMTPAccountName) = "My Name"
Flds(cdoSendUserReplyEmailAddress) = """User"" <user@microsoft.com>"
Flds(cdoSendEmailAddress) = """User"" <user@microsoft.com>"
' ... other settings
Flds.Update

Dim iMsg As New CDO.Message
Set iMsg.Configuration = iConf

' go on to use Message instance

Many of these settings can be loaded if Microsoft® Outlook® Express is installed on the local computer. Only the settings for the default account, default identity can be used. See Using Default Configuration Settings for more information.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Sending or Posting Using the Pickup Directory

To send messages using a local Simple Mail Transport Protocol (SMTP) pickup directory, perform the following steps:

  1. Set the http://schemas.microsoft.com/cdo/configuration/sendusing or http://schemas.microsoft.com/cdo/configuration/postusing field to cdoSendUsingPickup and CdoPostUsingPickup in the Configuration object, respectively.
  2. Set the following fields that are used with pickup directories:
    Name | Description
    smtppickupdirectory nntppickupdirectory | The full paths to the pickup directories for the SMTP and NNTP services. These values are normally automatically loaded when the Configuration object is created, if local services are installed.
    flushbuffersonwrite | Indicates whether to override file system buffering when writing the messages to the pickup directory. If set to True, the messages are committed directly to disk when written. Setting this field to True can cause performance degradation.

The following example demonstrates how to explicitly set various fields that are used when sending messages using the SMTP pickup directory on the local computer.

Visual Basic

' Reference to Microsoft ActiveX Data Objects 2.5 Library
' Reference to Microsoft CDO for Exchange 2000 Server Library
' ..
Dim iConf As New CDO.Configuration
Dim Flds  As ADODB.Fields
Set Flds = iConf.Fields

' Set the configuration for Network Send
Flds(cdoSendUsingMethod) = cdoSendUsingPickup
Flds(cdoSendUserReplyEmailAddress) = """User"" <user@microsoft.com>"
Flds(cdoSendEmailAddress) = """User"" <user@microsoft.com>"
' ... other settings
Flds.Update

Dim iMsg As New CDO.Message
Set iMsg.Configuration = iConf

' go on to use the Message object.

Many of these settings can be loaded if an SMTP service is installed on the local machine. See Using Default Configuration Settings for more information.

Related Topics

  • http://schemas.microsoft.com/cdo/configuration/smtpserverpickupdirectory
  • http://schemas.microsoft.com/cdo/configuration/nntpserverpickupdirectory
  • http://schemas.microsoft.com/cdo/configuration/flushbuffersonwrite

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Sending or Posting Using Exchange

To send messages using Microsoft® Exchange 2000 Server

  1. Set the http://schemas.microsoft.com/cdo/configuration/sendusing or http://schemas.microsoft.com/cdo/configuration/postusing field to cdoSendUsingExchange and CdoPostUsingExchange in the Configuration object.
  2. Set the http://schemas.microsoft.com/cdo/configuration/sendusername and http://schemas.microsoft.com/cdo/configuration/postusername fields to the e-mail address of the sender. These values are used to look up the Exchange service on which the sender's mailbox resides. Mail can only be submitted to the Exchange service containing the sender's mailbox.
  3. If desired, set the http://schemas.microsoft.com/cdo/configuration/activeconnection property to an open Microsoft® ActiveX® Data Objects (ADO) Connection object. The object must be bound to the user's mailbox.
  4. If desired, set the http://schemas.microsoft.com/cdo/configuration/mailboxurl to the user's mailbox URL. If set, this value is used to bind to the user's mailbox and send the message. If it is not set, the user's Exchange server is found in Microsoft® Active Directory™ and the URL to the mailbox is constructed. Note that the "mailbox" in this context is the user's root private store mailbox folder, not their inbox. For example, "file://./backofficestorage/domain.tld/mbx/user1".
  5. Set the following additional fields used when posting with Exchange:
    Name | Description
    http://schemas.microsoft.com/exchange/hardlinklist | A multivalued string containing the URLs to folders into which the item should be posted. Currently, only one URL can be specified.

The following example demonstrates explicitly setting various fields that are used when sending messages using Exchange 2000 Server:

Visual Basic

' Reference to Microsoft ActiveX Data Objects 2.5 Library
' Reference to Microsoft CDO for Exchange 2000 Server Library
' ..
Dim iConf As New CDO.Configuration
Dim Flds  As ADODB.Fields
Set Flds = iConf.Fields

Dim Conn As New ADODB.Connection
Conn.Provider = "ExOLEDB.DataSource"
' Note here: showing an HTTP URL but the
' location must be local to use the
' Exchange OLE DB Provider
Conn.Open "http://server/exchange/user1"

' Set the configuration for Network Send
Flds(cdoSendUsingMethod) = cdoSendUsingExchange
Flds(cdoSendUserReplyEmailAddress) = """User"" <user1@microsoft.com>"
Flds(cdoSendEmailAddress) = """User"" <user1@microsoft.com>"
Flds(cdoSendUserName) = "mailto:user1@microsoft.com"
Flds(cdoActiveConnection) = Conn
Flds(cdoMailboxURL) = "http://server/exchange/user1"
' ... other settings
Flds.Update

Dim iMsg As New CDO.Message
Set iMsg.Configuration = iConf

' go on to use the Message object

iMsg.Send ' Message is sent using the sender's local Exchange mailbox.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Configuring Network Authentication Information

When sending or posting messages over the network, many Simple Mail Transport Protocol (SMTP) and NNTP services require clients to authenticate themselves.

To configure a messaging object for authentication, perform the following steps:

  1. Set the http://schemas.microsoft.com/cdo/configuration/smtpauthenticate or http://schemas.microsoft.com/cdo/configuration/nntpauthenticate fields in the Configuration object's IConfiguration.Fields collection. The possible values are defined by the CdoProtocolsAuthentication enumeration.
  2. If the mechanism is set to cdoBasic, set the username and password. For SMTP, set the http://schemas.microsoft.com/cdo/configuration/sendusername and http://schemas.microsoft.com/cdo/configuration/sendpassword configuration fields. For NNTP, set the http://schemas.microsoft.com/cdo/configuration/postusername and http://schemas.microsoft.com/cdo/configuration/postpassword fields.

For the NTLM setting, the current process/thread security context is used to authenticate.

Visual Basic

' Reference to Microsoft ActiveX Data Objects 2.5 Library
' Reference to Microsoft CDO for Exchange 2000 Server Library
' ..
Dim iConf As New CDO.Configuration
Dim Flds  As ADODB.Fields
Set Flds = iConf.Fields

' Set the configuration
' Use string constants provided in the type library
' for field names (they are long)
Flds(cdoSendUsingMethod) = cdoSendUsingPort
Flds(cdoSMTPServer) = "mail.microsoft.com"
Flds(cdoSMTPServerPort) = 26
Flds(cdoSMTPConnectionTimeout) = 30
Flds(cdoSMTPAccountName) = "My Name"
Flds(cdoSendUserReplyEmailAddress) = """User"" <user@microsoft.com>"
Flds(cdoSendEmailAddress) = """User"" <user@microsoft.com>"
Flds(cdoSMTPAuthenticate) = cdoBasic
Flds(cdoSendUserName) = "name"
Flds(cdoSendPassword) = "password"
Flds.Update

Dim iMsg As New CDO.Message
Set iMsg.Configuration = iConf

' go on to use Message instance

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Setting Network Proxy Information

When using methods such as IMessage.AddAttachment and IMessage.CreateMHTMLBody, you may need to access network resources through a proxy server.

To set up the proxy configuration for a Message object, perform the following steps:

  1. Set the http://schemas.microsoft.com/cdo/configuration/urlproxyserver field in the Configuration object's IConfiguration.Fields collection.
  2. Set the http://schemas.microsoft.com/cdo/configuration/urlproxybypass field to the value "<local>". With this setting, the proxy service will be bypassed for local addresses. (This is an optional setting.)
  3. Set the http://schemas.microsoft.com/cdo/configuration/urlgetlatestversion field to force direct retrieval of resources and bypass the cache. (This is an optional setting.)

Visual Basic

' Reference to Microsoft ActiveX Data Objects 2.5 Library
' Reference to Microsoft CDO for Exchange 2000 Server Library
' ..
Dim iConf As New CDO.Configuration
Dim Flds  As ADODB.Fields
Set Flds = iConf.Fields

' Set the configuration
Flds(cdoSendUsingMethod) = cdoSendUsingPort
Flds(cdoSMTPServer) = "mail.microsoft.com"
Flds(cdoSMTPServerPort) = 26
Flds(cdoSMTPConnectionTimeout) = 30
Flds(cdoSMTPAccountName) = "My Name"
Flds(cdoSendUserReplyEmailAddress) = """User"" <user@microsoft.com>"
Flds(cdoSendEmailAddress) = """User"" <user@microsoft.com>"
Flds(cdoURLProxyServer) = "proxyserver:80"
Flds(cdoURLProxyBypass) = "<local>"
Flds(cdoURLGetLatestVersion) = True
Flds(cdoHTTPCookies) = "cookies here"
' ... other settings
Flds.Update

Dim iMsg As New CDO.Message
Set iMsg.Configuration = iConf

' go on to use Message instance

Related Topics

  • http://schemas.microsoft.com/cdo/configuration/urlproxyserver
  • http://schemas.microsoft.com/cdo/configuration/urlproxybypass
  • http://schemas.microsoft.com/cdo/configuration/urlgetlatestversion

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Using Default Configuration Settings

Default values are loaded when a Configuration object is created. The following sections discuss these default configuration values.

Local SMTP/NNTP Service

If the Simple Mail Transport Protocol (SMTP) or NNTP Service is installed on the local computer, CDO sets the SMTP pickup directory to the directory defined in the service properties, and sets the delivery method to use the pickup directory.

Outlook Express

If Microsoft® Outlook® Express is installed on the local computer, CDO gets default configuration settings from the Outlook Express properties that are defined for the default identity of the default account.

Because CDO automatically collects configuration information from the computer, you may not need to set these values manually. For example, if either the SMTP service or Outlook Express is installed, your application can send messages without having to explicitly configure the Message object. To change these settings, you can start with the default values and modify the fields you desire. Use the IConfiguration.Load method to load particular default settings on demand.

Note For performance reasons, it is recommended that you set up a single Configuration object and associate it with all messages rather than having CDO load the defaults for each sent message. For example, if using CDO in an Active Server Pages (ASP) application, you can store the Configuration class instance in the Session object, and then reuse it for each message sent during that session. If you use global settings, you could also place the object in the Application object.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Addressing the Message

To send a message, you must specify at least one recipient address by using the IMessage.To, IMessage.CC, or IMessage.BCC property. To post an NNTP message, you must specify at least one newsgroup address by using the IMessage.Newsgroups property.

Address Formats

The address formats are defined by various Internet standards:

SMTP Addresses

recipient@microsoft.com
<recipient@microsoft.com>
"Display Name" <recipient@microsoft.com>

NNTP Newsgroup Names

comp.os.windows
comp.microsoft.newsgroup1
Note Multiple addressees for a message are separated with commas only. The semicolons used with MAPI clients such as Microsoft® Outlook® are not used.
"Mr. A" <a@microsoft.com>, "Mr. B" <b@microsoft.com>
A@microsoft.com, <B@microsoft.com>, "Mr. C" <c@microsoft.com>
comp.microsoft.newsgroup1, comp.microsoft.newsgroups2

All addresses must be complete addresses or newsgroup names. The following examples show how to address a message by using the IMessage.To or IMessage.Newsgroups property.

Visual Basic

' Reference to Microsoft ActiveX Data Objects 2.5 Library
' Reference to Microsoft CDO for Exchange 2000 Server Library
' ..
Dim iMsg as New CDO.Message

iMsg.To         = "someone@microsoft.com"
iMsg.Newsgroups = "comp.microsoft.newsgroup"

C++, IDL

#import "c:\program files\common files\system\ado\msado15.dll" no_namespace
#import "c:\program files\common files\microsoft shared\cdo\cdoex.dll" no_namespace
// ...
IMessagePtr iMsg(__uuidof(Message));

iMsg->To         = "someone@microsoft.com";
iMsg->Newsgroups = "comp.microsoft.newsgroup";

VBScript

Dim iMsg
Set iMsg = CreateObject("CDO.Message")

iMsg.To         = "someone@microsoft.com"
iMsg.Newsgroups = "comp.microsoft.newsgroup"
Note Trailing commas are removed from address strings by the address field parser each time you set an address property. To concatenate address fields, place the comma at the beginning of the string being added. You can also concatenate the addresses prior to setting the value of the address field. This note applies to the To, CC, BCC, FollowUpTo, and Newsgroup properties. For example:
iMsg.To = "someone@microsoft.com"
iMsg.To = iMsg.To & ",another@microsoft.com"

The IMessage interface exposes properties that relate to the most common mail header fields, such as To, From, CC, BCC, Newsgroups and FollowUpTo. However, the complete list of headers for the message is contained in the IMessage.Fields collection. Fields that are used with a Message object reside in the urn:schemas:mailheader: and urn:schemas:httpmail: namespaces. Consequently, you can use the Fields collection to set mail header fields used to address the message.

Visual Basic

' Reference to Microsoft ActiveX Data Objects 2.5 Library
' Reference to Microsoft CDO for Exchange 2000 Server Library
' ..
Dim iMsg As New CDO.Message

Dim Flds As ADODB.Fields
Set Flds = iMsg.Fields
With Flds
  .Item("urn:schemas:mailheader:to") = "someone@microsoft.com"
  .Item("urn:schemas:mailheader:from") = "<another@microsoft.com>"
  .Item("urn:schemas:mailheader:cc") = "<thirdperson@microsoft.com>"
  .Update
End With
  ' ..

C++, IDL

#import "c:\program files\common files\system\ado\msado15.dll" no_namespace
#import "c:\program files\common files\microsoft shared\cdo\cdoex.dll" no_namespace
// ...
IMessagePtr iMsg(__uuidof(Message));

FieldsPtr Flds;
Flds = iMsg->Fields;
Flds->Item["urn:schemas:mailheader:to"]->Value =
_variant_t("someone@microsoft.com");
Flds->Item["urn:schemas:mailheader:from"]->Value =
_variant_t("<another@microsoft.com>");
Flds->Item["urn:schemas:mailheader:cc"]->Value =
_variant_t("<thirdperson@microsoft.com>");
Flds->Update();

VBScript

Dim iMsg
Set iMsg = CreateObject("CDO.Message")

Dim Flds
Set Flds = iMsg.Fields
With Flds
  .Item("urn:schemas:mailheader:to")   = "someone@microsoft.com"
  .Item("urn:schemas:mailheader:from") = "<another@microsoft.com>"
  .Item("urn:schemas:mailheader:cc")   = "<thirdperson@microsoft.com>"
  .Update
End With

Related Topics

  • IMessage.To
  • IMessage.CC
  • IMessage.BCC
  • IMessage.From
  • urn:schemas:mailheader: Namespace
  • urn:schemas:httpmail: Namespace

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Setting Subject and TextBody Fields

When sending a message, setting the subject field is optional, but usually specified. For posting a message to a newsgroup, setting the subject field is required. For both message types, setting the text body field is optional, but also typically provided.

You can set the subject and text body fields using the IMessage.Subject and IMessage.TextBody properties.

Visual Basic

' Reference to Microsoft ActiveX Data Objects 2.5 Library
' Reference to Microsoft CDO for Exchange 2000 Server Library
' ..
Dim iMsg As New CDO.Message

With iMsg
  .To = "someone@microsoft.com"
  .Newsgroups = "comp.microsoft.newsgroup1"
  .Subject = "Agenda for staff meeting"
  .TextBody = "Please plan to present your status for the following projects..."
End With

C++, IDL

#import "c:\program files\common files\system\ado\msado15.dll" no_namespace
#import "c:\program files\common files\microsoft shared\cdo\cdoex.dll" no_namespace
// ...
IMessagePtr iMsg(__uuidof(Message));

iMsg->To         = "someone@microsoft.com";
iMsg->Newsgroups = "comp.microsoft.newsgroup1";
iMsg->Subject    = "Agenda for staff meeting";
iMsg->TextBody   = "Please plan to present your status for the following projects...";

VBScript

Dim iMsg
Set iMsg = CreateObject("CDO.Message")

With iMsg
  .To         = "someone@microsoft.com"
  .Newsgroups = "comp.microsoft.newsgroup1"
  .Subject    = "Agenda for staff meeting"
  .TextBody   = "Please plan to present your status for the following projects..."
End With

You can use the IMessage.Fields collection to set the subject and text body fields of the message. The field names are urn:schemas:mailheader:subject, urn:schemas:httpmail:subject, and urn:schemas:httpmail:textdescription, respectively. The subject field within the urn:schemas:mailheader: returns the subject with any non-US-ASCII characters encoded according to Request for Comments (RFC) 1522. The subject field within the urn:schemas:httpmail: namespace contains the subject in Unicode characters.

Visual Basic

' Reference to Microsoft ActiveX Data Objects 2.5 Library
' Reference to Microsoft CDO for Exchange 2000 Server Library
' ..
Dim iMsg As New CDO.Message

Dim Flds As ADODB.Fields
Set Flds = iMsg.Fields
With Flds
  .Item("urn:schemas:httpmail:to") = "someone@microsoft.com"
  .Item("urn:schemas:httpmail:from") = "<another@microsoft.com>"
  .Item("urn:schemas:httpmail:cc") = "<thirdperson@microsoft.com>"

  .Item("urn:schemas:httpmail:subject") = "Agenda for the staff"
meeting ""
  .Item("urn:schemas:httpmail:textdescription") = "Please plan to present your status for the following projects..."
  .Update
End With

C++, IDL

#import "c:\program files\common files\system\ado\msado15.dll" no_namespace
#import "c:\program files\common files\microsoft shared\cdo\cdoex.dll" no_namespace
// ...
IMessagePtr iMsg(__uuidof(Message));

FieldsPtr Flds;
Flds = iMsg->Fields;
Flds->Item["urn:schemas:mailheader:to"] =
_variant_t("someone@microsoft.com");
Flds->Item["urn:schemas:mailheader:from"] =
_variant_t("<another@microsoft.com>");
Flds->Item["urn:schemas:mailheader:cc"] =
_variant_t("<thirdperson@microsoft.com>");
Flds->Item["urn:schemas:mailheader:subject"]->Value
     = _variant_t("Agenda for the staff meeting");
Flds->Item["urn:schemas:mailheader:textdescription"]->Value
     = _variant_t("Please plan to present your status for the following
projects...");
Flds->Update();

VBScript

Dim iMsg
Set iMsg = CreateObject("CDO.Message")

Dim Flds
Set Flds = iMsg.Fields
With Flds
  .Item("urn:schemas:httpmail:to")   = "someone@microsoft.com"
  .Item("urn:schemas:httpmail:from") = "<another@microsoft.com>"
  .Item("urn:schemas:httpmail:cc")   = "<thirdperson@microsoft.com>"

  .Item("urn:schemas:httpmail:subject")         = "Agenda for the staff
meeting"
  .Item("urn:schemas:httpmail:textdescription") = "Please plan to present
your status for the following projects..."
  .Update
End With

In addition to a plain text body, you can use HTML-formatted text using the IMessage.HTMLBody property. By default, the IMessage.AutoGenerateTextBody property in the object is set to True (VARIANT_TRUE), and therefore a plain text body is automatically generated from the HTML body text to support recipients whose clients cannot display HTML-formatted messages. For more information on creating attachments, see Creating MIME-Formatted Messages.

Related Topics

  • IMessage.Subject
  • IMessage.TextBody
  • IMessage.HTMLBody
  • IMessage.AutoGenerateTextBody
  • Creating MIME Formatted Messages

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Setting Message Header Fields

The most common message header fields are exposed as properties on the IMessage interface. However, all header fields are accessible in the IMessage.Fields collection. The header fields you can set by using this collection reside in the urn:schemas:mailheader: and urn:schemas:httpmail: namespaces. Additionally, the http://schemas.microsoft.com/exchange/sensitivity field is available.

You can add other headers not present in the provided default schema by adding the header to the collection within the urn:schemas:mailheader: field namespace.

Note Make sure to encode non US-ASCII characters when using the urn:schemas:mailheader: namespace using the mechanism defined in Request for Comments (RFC) 1522.

Visual Basic

' Reference to Microsoft ActiveX Data Objects 2.5 Library
' Reference to Microsoft CDO for Exchange 2000 Server Library
' ..
Dim iMsg As New CDO.Message

Dim Flds As ADODB.Fields
Set Flds = iMsg.Fields

With Flds
  .Item("urn:schemas:httpmail:to") = "someone@microsoft.com"
  .Item("urn:schemas:httpmail:from") = "another@microsoft.com"
  .Item("urn:schemas:httpmail:cc") = "thirdperson@microsoft.com"
  .Item("urn:schemas:httpmail:sender") = "myaddress@microsoft.com"

  .Item("urn:schemas:mailheader:myhdr") = "some value"
  .Item("urn:schemas:mailheader:X-Hdr") = "less value"

  .Update
End With

C++, IDL

#import "c:\program files\common files\system\ado\msado15.dll" no_namespace
#import "c:\program files\common files\microsoft shared\cdo\cdoex.dll" no_namespace
// ...
IMessagePtr iMsg(__uuidof(Message));

FieldsPtr Flds;
Flds = iMsg->Fields;

Flds->Item["urn:schemas:httpmail:to"]->Value
      = _variant_t("someone@microsoft.com");
Flds->Item["urn:schemas:httpmail:from"]->Value
      = _variant_t("another@microsoft.com");
Flds->Item["urn:schemas:httpmail:cc"]->Value
      = _variant_t("thirdperson@microsoft.com");
Flds->Item["urn:schemas:httpmail:sender"]->Value
      = _variant_t("myaddress@microsoft.com");

Flds->Item["urn:schemas:mailheader:myhdr"]->Value
     = _variant_t("some value");
Flds->Item["urn:schemas:mailheader:X-Header"]->Value
     = _variant_t("another value");
Flds->Update();

VBScript

Dim iMsg
Set iMsg = CreateObject("CDO.Message")

Dim Flds
Set Flds = iMsg.Fields

With Flds
  .Item("urn:schemas:httpmail:to")      = "someone@microsoft.com"
  .Item("urn:schemas:httpmail:from")   = "another@microsoft.com"
  .Item("urn:schemas:httpmail:cc")     = "thirdperson@microsoft.com"
  .Item("urn:schemas:httpmail:sender") = "myaddress@microsoft.com"
  .Item("urn:schemas:mailheader:myhdr") = "some value"
  .Item("urn:schemas:mailheader:X-Hdr") = "less value"
  .Update
End With
Tip When using the Fields collection, remember to invoke the Update method to commit any changes, deletions, or additions. If the CDO object is currently bound, invoke IDataSource.Save to commit the changes to the data source.

Note that in the example above, the Field.Item method was used to retrieve the Field object from the collection. You can also use the Fields.Append method. For CDO applications, the Item method will return the appropriate Field object regardless of whether it currently exists in the collection.

Related Topics

  • IMessage Interface
  • urn:schemas:mailheader: Namespace
  • urn:schemas:httpmail: Namespace
  • urn:schemas:mailheader:sensitivity

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Adding Attachments

The IMessage.AddAttachment method adds an attachment to a message. The AddAttachment method accepts a file, ftp, http, or https URL parameter that identifies the location of the attachment. The method returns a reference to the newly added BodyPart object that houses the attachment so that it can be further manipulated, if necessary.

The following example shows how to add a Graphics Interchange Format (GIF) graphic and a Microsoft® Word file as attachments to a message.

Visual Basic

' Reference to Microsoft ActiveX Data Objects 2.5 Library
' Reference to Microsoft CDO for Exchange 2000 Server Library
' ..
Dim iMsg As New CDO.Message
' configure message here if necessary
With iMsg
   .To = "someone@microsoft.com"
   .From = "another@microsoft.com"
   .Newsgroups = "comp.microsoft.newsgroup1"
   .Subject = "Agenda for staff meeting"
   .TextBody = "See attached docs for more info."
   .AddAttachment "http://example.microsoft.com/picture.gif"
   .AddAttachment "file://d:/temp/test.doc"
   .AddAttachment "C:\files\another.doc"
   ' finish and send
End With

C++, IDL

#import "c:\program files\common files\system\ado\msado15.dll" no_namespace
#import "c:\program files\common files\microsoft shared\cdo\cdoex.dll" no_namespace
// ...
IMessagePtr iMsg(__uuidof(Message));

/*
** configure message here if necessary
*/

iMsg->To         = "someone@microsoft.com";
iMsg->From       = "another@microsoft.com";
iMsg->Newsgroups = "comp.microsoft.newsgroup1";
iMsg->Subject    = "Agenda for staff meeting";
iMsg->TextBody   = "See attached docs for more info.";

try {
  iMsg->AddAttachment("http://example.microsoft.com/picture.gif","","");
  iMsg->AddAttachment("file://d:/temp/test.doc","","");
  iMsg->AddAttachment("C:\files\another.doc","","");
}
catch(_com_error err) {
  // handle exception
}
// finish and send

VBScript

Dim iMsg
Set iMsg = CreateObject("CDO.Message")
' configure message here if necessary
With iMsg
   .To   = "someone@microsoft.com"
   .From = "another@microsoft.com"
   .Newsgroups = "comp.microsoft.newsgroup1"
   .Subject  = "Agenda for staff meeting"
   .TextBody = "See attached docs for more info."
   .AddAttachment "http://example.microsoft.com/picture.gif"
   .AddAttachment "file://d:/temp/test.doc"
   .AddAttachment "C:\files\another.doc"
   ' ..
End With
Note If you attach a Web page using the AddAttachment method, you attach only the file specified in the URL. If the page contains image links or other content, they are not included. To attach a full Web page with embedded graphics, use the IMessage.CreateMHTMLBody method. For more information about attaching Web pages, see Creating MHTML-Formatted Messages.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Manually Adding Attachments

You can manually add attachments directly to the IMessage.Attachments or IBodyPart.BodyParts collection that is exposed by the Message object. This approach is useful if you have content that is not on the file system or URL-addressable. When manually adding an attachment, use the IMessage.Attachments collection as described in the following procedure:

  1. Create a new BodyPart object in the Attachments collection using IBodyParts.Add. (The Attachments property on the object returns a BodyParts collection object reference.)
  2. Set appropriate Multipurpose Internet Mail Extensions (MIME) header fields for the body part.
  3. Obtain the content stream for the attachment using IBodyPart.GetDecodedContentStream and write the content to it.
  4. Call _Stream.Flush to commit written data to the body part.

Visual Basic

Dim iMsg As New CDO.Message

Dim iBp As CDO.IBodyPart
Dim Stm As ADODB.Stream
Dim Flds As ADODB.Fields

With iMsg
   .To = "someone@microsoft.com"
   .From = "another@microsoft.com"
   .Newsgroups = "comp.microsoft.newsgroup1"
   .Subject = "Agenda for staff meeting"
   .TextBody = "Please plan to present your status for the following projects..."
   Set iBp = .Attachments.Add
   Set Flds = iBp.Fields

   With Flds
      .Item("urn:schemas:mailheader:content-type") = "text/plain; name=test.txt"
      .Item("urn:schemas:mailheader:content-transfer-encoding") = "quoted printable """
      .Update
   End With          ' Flds
   Set Flds = Nothing
   Set Stm = iBp.GetDecodedContentStream
   ' Because body part content-type is "text", the returned Stream
   '    is of type adTypeText.  Use WriteText to fill the stream
   Stm.WriteText "Here is the text in the ""attachment"" called text.txt"
   ' commit the changes into the BodyPart object
   Stm.Flush
   Set Stm = Nothing
End With          ' iMsg

C++, IDL

#import "c:\program files\common files\system\ado\msado15.dll" no_namespace
#import "c:\program files\common files\microsoft shared\cdo\cdoex.dll" no_namespace
// ...
IMessagePtr iMsg(__uuidof(Message));
IBodyPartPtr iBp;
_StreamPtr Stm;
FieldsPtr Flds;

iMsg->To         = "someone@microsoft.com";
iMsg->From       = "another@microsoft.com";
iMsg->Subject    = "Agenda for staff meeting";
iMsg->TextBody   = "Please plan to present your status for the following
projects...";

iBp  = iMsg->Attachments->Add(-1);
Flds = iBp->Fields;
Flds->Item["urn:schemas:mailheader:content-type"]->Value
    =  _variant_t("text/plain;  name=\"test.txt\"");
Flds->Update();

Stm = iBp.GetDecodedContentStream();
  /*
   **  Because body part content-type is "text", the returned Stream
   **  is of type adTypeText.  Use WriteText to fill the stream
   */
Stm->WriteText("Here is the text in the ""attachment"" called
text.txt",adWriteChar);
   ' commit the changes into the BodyPart object
Stm->Flush();

// ...
if(g_Debug)
   cout << iMsg->GetStream()->ReadText(-1);

VBScript

Dim iMsg
Set iMsg = CreateObject("CDO.Message")
Dim iBp
Dim Stm
Dim Flds

With iMsg
   .To         = "someone@microsoft.com"
   .From       = "another@microsoft.com"
   .Subject    = "Agenda for staff meeting"
   .TextBody   = "Please plan to present your status for the following
projects..."
   Set iBp  = .Attachments.Add
   Set Flds = iBp.Fields

   With Flds
      .Item("urn:schemas:mailheader:content-type")              =
"text/plain; name=test.txt"
      .Item("urn:schemas:mailheader:content-transfer-encoding") = "quoted
printable"
      .Update
   End With          ' Flds
   Set Flds = Nothing
   Set Stm = iBp.GetDecodedContentStream
   ' Because body part content-type is "text", the returned Stream
   '    is of type adTypeText.  Use WriteText to fill the stream
   Stm.WriteText "Here is the text in the ""attachment"" called text.txt"
   ' commit the changes into the BodyPart object
   Stm.Flush
   Set Stm = Nothing
End With          ' iMsg

You can add any type of attachment to a message. For MIME-formatted messages, attachments are added as MIME body parts. CDO automatically sets the MIME Content-Type and Content-Transfer-Encoding values for some attachments, but for some attachment types you need to set these values explicitly.

If you want to have the message sent with attachments formatted and encoded with Unix-to-Unix encode (UUENCODE), set the IMessage.MIMEFormatted property to False before sending the message.

In many cases, you might need to specify credentials to access a resource on the network. Add this information to the Message object's associated Configuration object. See Configuring the Message Object for more information.

Related Topics

  • IMessage.CreateMHTMLBody Method
  • IMessage.Attachments Property
  • Creating MHTML-Formatted Messages

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Creating MIME-Formatted Messages

By default, the CDO components construct message body content using MIME encoding format. This process is controlled by using the IMessage.MIMEFormatted property, which defaults to True. There are many ways to create the MIME content hierarchy in a message. In most cases, when adding an attachment or creating a MIME Encapsulation of Aggregate HTML Documents (MHTML) message, the IMessage interface exposes methods that automatically structure the MIME content and manage the underlying details. These methods include IMessage.AddAttachment and IMessage.CreateMHTMLBody. To add attachments to a message in UUEncoded format, set IMessage.MIMEFormatted to False.

In many cases, you might need to manually construct all or part of the body part hierarchy.

Objects that participate in the body part hierarchy for a message expose implementations of the IBodyPart interface. For example, each instance of the BodyPart and Message Component Object Model (COM) classes represents one body part in the hierarchy of a MIME-encoded message. Both BodyPart and Message instances expose the IBodyPart interface to facilitate manipulation of the body part's content and properties. The IBodyPart.BodyParts collection contains the child BodyPart objects for the object and is therefore used to navigate down the hierarchy of objects. To navigate up the hierarchy from an object, you use the IBodyPart.Parent property.

The Message object acts as the root of the MIME hierarchy. In standard object-oriented fashion, the hierarchies extend in patterns of BodyPart -> BodyParts -> BodyPart until a terminating (leaf) node in the hierarchy is reached.

When using methods such as IMessage.CreateMHTMLBody or IMessage.AddAttachment, or the HTMLBody property on the message, the MIME hierarchy is constructed automatically. You do not need to manually add the BodyPart objects that contain the various content parts.

In many cases, you might want to manually create the BodyPart hierarchy. To do so, you can use the IBodyPart.AddBodyPart method to add child body parts to the object. Alternatively, you can access the IBodyPart.BodyParts collection explicitly and use the IBodyParts.Add method to add the new body part. Both methods create a new BodyPart instance and return an object reference on the newly added object. Using this returned interface, you can then set any fields for the object using the IBodyPart.Fields collection. For body parts that contain content, use the appropriate Stream object to populate the content. Access the BodyPart Stream object by using either IBodyPart.GetEncodedContentStream or IBodyPart.GetDecodedContentStream.

Related Topics

  • IMessage.AddAttachment Method
  • IMessage.CreateMHTMLBody Method
  • IMessage.MIMEFormatted Property
  • IBodyPart.AddBodyPart Method
  • IBodyParts.Add Method

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Adding BodyPart Objects to the MIME Hierarchy

The following example demonstrates creating a common Multipurpose Internet Mail Extensions (MIME) hierarchy for a message that contains two alternate representations of the message text: text/plain and text/html. The steps are as follows:

  1. Create the Message object, and retrieve its IBodyPart interface.
  2. Use the IBodyPart.AddBodyPart method to create and add a child BodyPart object.
  3. Use the returned IBodyPart object reference to set fields for the object by using its IBodyPart.Fields collection.
  4. If this body part is to directly contain content, you can add this content by retrieving a Stream object by using the IBodyPart.GetDecodedContentStream method. Write the data to the Stream object, and call _Stream.Flush to commit the stream to the BodyPart object.

Visual Basic

' Reference to Microsoft ActiveX Data Objects 2.5 Library
' Reference to Microsoft CDO for Exchange 2000 Server Library
' ..
Dim iMsg As New CDO.Message
Dim iBp  As CDO.IBodyPart
Dim iBp1 As CDO.IBodyPart
Dim Flds As ADODB.Fields
Dim Stm  As ADODB.Stream

' Get IBodyPart on the Message object
Set iBp = iMsg

' TEXT BODYPART
' Add the body part for the text/plain part of message
Set iBp1 = iBp.AddBodyPart

' set the fields here
Set Flds = iBp1.Fields
Flds("urn:schemas:mailheader:content-type") = "text/plain; charset=""iso-8859-1"""
Flds.Update

' get the stream and add the message
Set Stm = iBp1.GetDecodedContentStream
Stm.WriteText "this is the message in text format"
Stm.Flush

' HTML BODYPART
' Do the HTML part here
Set iBp1 = iBp.AddBodyPart

' set the content-type field here
Set Flds = iBp1.Fields
Flds("urn:schemas:mailheader:content-type") = "text/html"
Flds.Update

' get the stream and add message HTML text to it
Set Stm = iBp1.GetDecodedContentStream
Stm.WriteText "<HTML><H1>this is some content for the body part object</H1></HTML>"
Stm.Flush

' Now set the Message object's Content-Type header
' to multipart/alternative
Set Flds = iBp.Fields
Flds("urn:schemas:mailheader:content-type") = "multipart/alternative"
Flds.Update

C++, IDL

#import "c:\program files\common files\system\ado\msado15.dll" no_namespace
#import "c:\program files\common files\microsoft shared\cdo\cdoex.dll" no_namespace
// ...
IMessagePtr iMsg(__uuidof(Message));
IBodyPartPtr iBp;
IBodyPartPtr iBp1;
FieldsPtr Flds;
_StreamPtr Stm;

// Get IBodyPart on the Message object
iBp = iMsg;

// TEXT BODYPART
// Add the body part for the text/plain part of message
iBp1 = iBp->AddBodyPart(-1);

' set the fields here
Flds = iBp1->Fields();
Flds->Item["urn:schemas:mailheader:content-type"]->Value
   = _variant_t("text/plain; charset=""iso-8859-1""");
Flds->Update();

// get the stream and add the message
Stm = iBp1->GetDecodedContentStream();
Stm->WriteText("this is the message in text format",adWriteLine);
Stm->Flush();

// HTML BODYPART
// Do the HTML part here
iBp1 = iBp->AddBodyPart(-1);

// set the content-type field here
Flds = iBp1->Fields;
Flds->Item["urn:schemas:mailheader:content-type"]->Value
   = _variant_t("text/html");
Flds->Update();

// get the stream and add message HTML text to it
Stm = iBp1->GetDecodedContentStream();
Stm->WriteText("<HTML><H1>this is some content for the body part
object</H1></HTML>",adWriteLine);
Stm->Flush();

// Now set the Message object's Content-Type header
// to multipart/alternative
Flds = iBp->Fields;
Flds->Item["urn:schemas:mailheader:content-type"]->Value
     = _variant_t("multipart/alternative");
Flds->Update();

VBScript

Dim iMsg
Dim iBp
Dim iBp1
Dim Flds
Dim Stm

Set iMsg = CreateObject("CDO.Message")
' Get IBodyPart on the Message object
Set iBp = iMsg.BodyPart

' TEXT BODYPART
' Add the body part for the text/plain part of message
Set iBp1 = iBp.AddBodyPart

' set the fields here
Set Flds = iBp1.Fields
Flds("urn:schemas:mailheader:content-type") = "text/plain; charset=""iso
8859-1"""
Flds.Update

' get the stream and add the message
Set Stm = iBp1.GetDecodedContentStream
Stm.WriteText "this is the message in text format"
Stm.Flush

' HTML BODYPART
' Do the HTML part here
Set iBp1 = iBp.AddBodyPart

' set the content-type field here
Set Flds = iBp1.Fields
Flds("urn:schemas:mailheader:content-type") = "text/html"
Flds.Update

' get the stream and add message HTML text to it
Set Stm = iBp1.GetDecodedContentStream
Stm.WriteText "<HTML><H1>this is some content for the body part
object</H1></HTML>"
Stm.Flush

' Now set the Message object's Content-Type header
' to multipart/alternative
Set Flds = iBp.Fields
Flds("urn:schemas:mailheader:content-type") = "multipart/alternative"
Flds.Update

Related Topics

  • IMessage.MIMEFormatted Property
  • IBodyPart.AddBodyPart Method
  • IBodyParts.Add Method
  • IBodyPart.Fields Property
  • IBodyPart.GetDecodedContentStream Method

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Setting Header Fields on Body Parts

CDO automatically sets the fields needed for typical Multipurpose Internet Mail Extensions (MIME) messages. For example, when you create IMessage.HTMLBody with the IMessage.AutoGenerateTextBody property set to True, IMessage.TextBody is automatically generated along with the appropriate MIME structure. The IBodyPart.ContentMediaType for the root part is automatically set to multipart/alternative, and the two subparts are set to text/plain and text/html.

For more complex MIME-formatted messages, you might need to set the header fields directly. All fields are stored in a Microsoft® ActiveX® Data Objects (ADO) Fields collection as name/value pairs. The mail header fields used with body parts reside in the urn:schemas:mailheader: namespace. Common fields such as urn:schemas:mailheader:content-type are also exposed as properties of the IBodyPart interface.

The following example shows how to set the ADO field urn:schemas:mailheader:content-language of the root body part of a simple message to German ("de").

Visual Basic

' Reference to Microsoft ActiveX Data Objects 2.5 Library
' Reference to Microsoft CDO for Exchange 2000 Server Library
' ..
Dim iMsg As New CDO.Message
Dim iBp  As CDO.IBodyPart
Set iBp = iMsg

Dim Flds As ADODB.Fields
Set Flds = iBp.Fields
Flds("urn:schemas:mailheader:content-language") = "de"
Flds.Update

C++, IDL

#import "c:\program files\common files\system\ado\msado15.dll" no_namespace
#import "c:\program files\common files\microsoft shared\cdo\cdoex.dll" no_namespace
// ...
IMessagePtr iMsg(__uuidof(Message));
IBodyPartPtr iBp;
FieldsPtr Flds;

iBp = iMsg;
Flds = iBp->Fields;
Flds->Item["urn:schemas:mailheader:content-language"] = _variant_t("de");
Flds->Update();

VBScript

Dim iMsg
Dim iBp
Set iBp = iMsg.BodyPart

Dim Flds
Set Flds = iBp.Fields
Flds("urn:schemas:mailheader:content-language") = "de"
Flds.Update

Related Topics

  • urn:schemas:mailheader:content-type Field
  • urn:schemas:mailheader:content-language Field
  • urn:schemas:mailheader: Namespace

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Creating MHTML-Formatted Messages

MIME Encapsulation of Aggregate HTML Documents (MHTML) formatting provides a simple way to send an entire Web page, or portions of one, as a message. The message includes all of the HTML formatting, graphics, and other elements that are contained in the original page. You can also choose to exclude one or more types of elements from the message.

The IMessage.CreateMHTMLBody method accepts a URL parameter and a flags parameter. The URL specifies the Web page being sent, and the optional flags specify the types of elements to exclude from the message. CDO makes the file specified by the URL the IMessage.HTMLBody of the message, and each graphic or other element referenced in that file becomes a MIME body part. By default, CDO automatically generates the text body that contains a plain text version of the HTMLBody content.

CDO must be able to access the specified source URL to create the message. If CDO needs to use a proxy server to reach a URL outside a firewall, set this location for the http://schemas.microsoft.com/cdo/configuration/urlproxyserver field in the Message object's associated Configuration object.

The following example shows how to create a message from a Web page.

Visual Basic

' Reference to Microsoft ActiveX Data Objects 2.5 Library
' Reference to Microsoft CDO for Exchange 2000 Server Library
' ..
Dim iMsg  As New CDO.Message
Dim iConf As New CDO.Configuration
Dim Flds  As ADODB.Fields

Set Flds = iConf.Fields
Flds("http://schemas.microsoft.com/cdo/configuration/urlproxyserver") = "proxyname:80"
Flds("http://schemas.microsoft.com/cdo/configuration/urlproxybypass") = "<local>"
Flds("http://schemas.microsoft.com/cdo/configuration/urlgetlatestversion") = True
Flds.Update

Set iMsg.Configuration = iConf

iMsg.CreateMHTMLBody "http://example.microsoft.com", _
                     cdoSuppressAll, _
                     "domain\username", _
                     "password"

' ...

C++, IDL

#import "c:\program files\common files\system\ado\msado15.dll" no_namespace
#import "c:\program files\common files\microsoft shared\cdo\cdoex.dll" no_namespace
// ...
IMessagePtr       iMsg(__uuidof(Message));
IConfigurationPtr iConf(__uuidof(Configuration));
FieldsPtr         Flds;

Flds = iConf->Fields;
Flds
>Item["http://schemas.microsoft.com/cdo/configuration/urlproxyserver"]
>Value
  = _variant_t("myproxyserver:80");
Flds
>Item["http://schemas.microsoft.com/cdo/configuration/urlproxybypass"]
>Value
  = _variant_t("<local>");
Flds
>Item["http://schemas.microsoft.com/cdo/configuration/urlgetlatestversion
]->Value
  = _variant_t(VARIANT_TRUE);
Flds->Update();
iMsg->Configuration = iConf;
try
{
  iMsg->CreateMHTMLBody(
           "http://example.microsoft.com",
           cdoSuppressAll,
           "domain\\username",
           "password");
}
catch(_com_error err)
{
  // handle exception
}

VBScript

Dim iMsg
Dim iConf
Dim Flds

Set iMsg = CreateObject("CDO.Message")
Set iConf = CreateObject("CDO.Configuration")

Set Flds = iConf.Fields
Flds("http://schemas.microsoft.com/cdo/configuration/urlproxyserver") =
"proxyname:80"
Flds("http://schemas.microsoft.com/cdo/configuration/urlproxybypass") =
"<local>"
Flds("http://schemas.microsoft.com/cdo/configuration/urlgetlatestversion")
= True
Flds.Update

Set iMsg.Configuration = iConf

iMsg.CreateMHTMLBody "http://example.microsoft.com", _
                      cdoSuppressAll, _
                      "domain\username", _
                      "password"
Note To suppress multiple elements, add the values of the flag constants. For example, to suppress images and style sheets, specify the flags parameter as (cdoSuppressImages + cdoSuppressStyleSheets).

Related Topics

  • http://schemas.microsoft.com/cdo/configuration/urlproxyserver Field
  • IMessage.CreateMHTMLBody Method
  • cdoMHTMLFlags Enum

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Specifying the Header Fields Character Set

A Multipurpose Internet Mail Extensions (MIME)-formatted message can use one character set for the text or HTML body parts, and another character set for the message header fields. In this case, the character set for the header fields must be explicitly set so that the fields are properly encoded using the mechanism defined by Request for Comments (RFC) 1522.

The following example demonstrates how to explicitly set the character set for the message header fields to iso-2022-jp, whereas the explicit character set for an included HTML body part is iso-8859-9.

Visual Basic

' Reference to Microsoft ActiveX Data Objects 2.5 Library
' Reference to Microsoft CDO for Exchange 2000 Server Library
' ..
Dim iMsg As New CDO.Message
With iMsg
  .From = """[Japanese Unicode characters]"" <sender@microsoft.com>"
  .To = """[Japanese Unicode characters]"" <recipient@microsoft.com>"
  .Subject = "[Japanese Unicode characters]"

  ' The character set is iso-8859-1 for the HTML in included Web page
  ' and for the text/plain alternative message text
  .CreateMHTMLBody "http://www.microsoft.com"

  ' The next line sets the character set for the message header fields
  ' to iso-2022-jp.
  .BodyPart.Charset = "iso-2022-jp"
  .Send
End With

C++, IDL

#import "c:\program files\common files\system\ado\msado15.dll" no_namespace
#import "c:\program files\common files\microsoft shared\cdo\cdoex.dll" no_namespace
// ...
IMessagePtr iMsg(__uuidof(Message));
iMsg->To   = """[Japanese Unicode characters]"" <sender@microsoft.com>";
iMsg->From = """[Japanese Unicode characters]""
<recipient@microsoft.com>";
iMsg->Subject = "[Japanese Unicode characters]";
  /*
  **  The character set is iso-8859-1 for the HTML in the
  **  included Web page and for the text/plain alternative message text
  */
iMsg->CreateMHTMLBody("http://www.microsoft.com",cdoSuppressNone,"","");

  /*
  ** Now, set the character set for the message header fields
  ** so that they are encoded properly (RFC 1522).
  */
IBodyPartPtr iBp;
iBp = iMsg;
iBp->Charset = "iso-2022-jp";

iMsg->Send();

VBScript

Dim iMsg
Set iMsg = CreateObject("CDO.Message")
With iMsg
  .From    = """[Japanese Unicode characters]"" <sender@microsoft.com>"
  .To      = """[Japanese Unicode characters]"" <recipient@microsoft.com>"
  .Subject = "[Japanese Unicode characters]"

  ' The character set is iso-8859-1 for the HTML in included Web page
  ' and for the text/plain alternative message text
  .CreateMHTMLBody "http://www.microsoft.com"

  ' This next line sets the character set for the message header fields
  ' to iso-2022-jp.
  .BodyPart.Charset = "iso-2022-jp"
  .Send
End With

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Sending and Posting Messages

To send a message, use the IMessage.Send method. Before you can send a message, you must set at least one recipient address and one sender address. You can use the To and From properties for the Message object to do so.

To post a message, use the IMessage.Post method. Before you can post a message, you must set at least the From, Subject, and Newsgroups message header fields for the object. You can use either the IMessage.From, IMessage.Subject, and IMessage.Newsgroups properties for the Message object.

The following example demonstrates these steps using IMessage interface properties and fields in the IMessage.Fields collection.

Visual Basic

' Reference to Microsoft ActiveX Data Objects 2.5 Library
' Reference to Microsoft CDO for Exchange 2000 Server Library
' ..
Dim iMsg As New CDO.Message
' configure object here if necessary
With iMsg
   .From = "Someone@Somewhere.microsoft.com"
   .CC = "Another@microsoft.com"
   .Subject = "Your lights are on, but no one is home"
   .TextBody = "You left your lights on this morning."
   .Newsgroups = "somewhere.general"
   .Post
   .Newsgroups = ""
   .To = "SomeoneElse@Somewhere.microsoft.com"
   .Fields(cdoDispositionNotificationTo) = "Someone@somewhere.microsoft.com"
   .Fields.Update
   .Send
End With

Set iMsg = Nothing

C++, IDL

#import "c:\program files\common files\system\ado\msado15.dll" no_namespace
#import "c:\program files\common files\microsoft shared\cdo\cdoex.dll" no_namespace
// ...
IMessagePtr iMsg(__uuidof(Message));
iMsg->From     = "Someone@Somewhere.microsoft.com";
iMsg->CC       = "Another@microsoft.com";
iMsg->Subject  = "Your lights are on, but no one is home";
iMsg->TextBody = "You left your lights on this morning.";
iMsg->Newsgroups = "somewhere.general";
iMsg->Post();
iMsg->Newsgroups = "";
iMsg->To       = "SomeoneElse@Somewhere.microsoft.com";
iMsg->Fields->Item[cdoDispositionNotificationTo]->Value =
_variant_t("someone@somewhere.microsoft.com");
iMsg->Fields->Update();
iMsg->Send();
iMsg = NULL;

VBScript

Dim iMsg
Set iMsg = CreateObject("CDO.Message")
' configure object here if necessary
With iMsg
   .From     = "Someone@Somewhere.microsoft.com"
   .CC       = "another@microsoft.com"
   .Subject  = "Your lights are on, but no one is home"
   .TextBody = "You left your lights on this morning."
   .Newsgroups = "somewhere.general"
   .Post

   .Newsgroups = ""
   .To       = "SomeoneElse@Somewhere.microsoft.com"
   .Fields(cdoDispositionNotificationTo) =
"someone@somewhere.microsoft.com"
   .Fields.Update
   .Send
End With

Set iMsg = Nothing

The mechanism for sending or posting messages is controlled through configuration settings associated with the object. For more information, see Configuring the Message Object.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Sending Using Exchange

When sending mail by using Microsoft® Exchange 2000 Server, CDO uses the Exchange Mail Submission Uniform Resource Identifier (URI) for the user to transmit the message. This URI is available from the urn:schemas:httpmail:sendmsg property for the user's root private mailbox folder. When sending a message using Exchange, an OLE DB provider is used.

A special set of configuration properties can be set when sending messages using Exchange. Each property in the following table is within the http://schemas.microsoft.com/cdo/configuration/ namespace unless denoted otherwise.

Property Name | Description
mailboxurl | The URL to the user's Exchange mailbox. This URL can be in either file: or http: URL scheme format. If this property is not set, CDO looks up the user's mailbox URL using Microsoft® Active Directory™ and the user principle name (UPN) in the sendusername property.
activeconnection | An open Microsoft® ActiveX® Data Objects (ADO) Connection object to the user's mailbox. If this property is set, the connection is used to look up the user's mail submission URI, to bind to the user's mail submission URI, and transmit the message. Set this property if you do not want a currently bound Message object to rebind to the user's mailbox when sending a message using Exchange. When messages are sent using Exchange, CDO normally binds to the user's mailbox, and the current DataSource binding is changed.
urlsource | What source the URL in the mailboxurl property is set to. Currently, the only supported value is cdoExchangeMailboxURL, which is the default.
sendusername | The user's user principle name. For example, mailto:user1@domain.tld or user1@domain.tld.
sendpassword | The user's password.

The following examples demonstrate sending messages using Exchange.

VBScript

' Assume constants have been imported into scripting host.
' For example,
' <reference object="adodb.record"/>
' <reference object="cdo.message"/>
' when using Windows Scripting Host

Sub SendMailUsingExchange(sMailboxURL, sTo, sFrom, sSubject, sText)

  ' Assume type information has been imported into the scripting host.
  ' e.g. <reference object="CDO.Message"/> in .wsf script file.
  Set Msg = CreateObject("CDO.Message")
  Set Conf = Msg.Configuration

  Conf("http://schemas.microsoft.com/cdo/configuration/sendusing")  = cdoSendUsingExchange
  Conf("http://schemas.microsoft.com/cdo/configuration/mailboxurl") = sMailboxURL
  Conf.Fields.Update

  Msg.To       = sTo
  Msg.From     = sFrom
  Msg.Subject  = sSubject
  Msg.TextBody = sText

  Msg.Send

End Sub

Sub SendMailWithConnectionTrans( sMailboxURL, Conn, sTo, sFrom, sSubject, sText)

  ' Assume type information has been imported into the scripting host.
  ' e.g. <reference object="CDO.Message"/> in .wsf script file.

  Set Msg  = CreateObject("CDO.Message")
  Set Conf = CreateObject("CDO.Configuration")
  Set Msg.Configuration = Conf

  Conf("http://schemas.microsoft.com/cdo/configuration/sendusing")  = cdoSendUsingExchange
  Conf("http://schemas.microsoft.com/cdo/configuration/mailboxurl") = sMailboxURL
  Conf("http://schemas.microsoft.com/cdo/configuration/activeconnection") = Conn
  Conf.Fields.Update

  Msg.To       = sTo
  Msg.From     = sFrom
  Msg.Subject  = sSubject
  Msg.TextBody = sText

  Conn.BeginTrans
  Msg.Send
  Conn.CommitTrans

End Sub

Sub SendMailWithConnection( sMailboxURL, Conn, sTo, sFrom, sSubject, sText)

  ' Assume type information has been imported into the scripting host.
  ' e.g. <reference object="CDO.Message"/> in .wsf script file.

  Set Msg  = CreateObject("CDO.Message")
  Set Conf = CreateObject("CDO.Configuration")
  Set Msg.Configuration = Conf

  Conf("http://schemas.microsoft.com/cdo/configuration/sendusing")        = cdoSendUsingExchange
  Conf("http://schemas.microsoft.com/cdo/configuration/mailboxurl")       = sMailboxURL
  Conf("http://schemas.microsoft.com/cdo/configuration/activeconnection") = Conn
  Conf.Fields.Update

  Msg.To       = sTo
  Msg.From     = sFrom
  Msg.Subject  = sSubject
  Msg.TextBody = sText

  Msg.Send

End Sub

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Posting Using Exchange

When posting using Microsoft® Exchange 2000 Server, CDO uses either the NNTP protocol or posts the message directly to a folder specified in the hardlinklist configuration property.

A special set of configuration properties can be set when posting messages using Exchange. Each property in the following table is within the http://schemas.microsoft.com/cdo/configuration/ namespace unless denoted otherwise.

Property Name | Description
http://schemas.microsoft.com/exchange/hardlinklist | An array of URLs that identify public folders in which to post the message. Currently, only one URL can be set in the array. If set, the Newsgroups property is ignored, and an OLE DB provider is used to post the message directly to the public folder. To avoid rebinding the object's data source, specify an open Connection object to use when posting in the activeconnection property.
activeconnection | An open Microsoft® ActiveX® Data Objects (ADO) Connection object to the public store in which the folder specified in the hardlinklist property resided. If this property is set, the connection is used to post the message to the public folder. You set this property if you do not want a currently bound Message object to rebind to the folder when posting. Normally, when messages are posted using Exchange to the folders in the hardlinklist property, CDO binds to the folderx, and the current DataSource binding for the object is therefore changed.
postusername | The user's user principle name (UPN). For example, mailto:user1@domain.tld or user1@domain.tld. This username is used along with the password to post messages directly to folders on remote Exchange servers.
postpassword | The user's password.

The following examples demonstrate posting messages using Exchange directly to a particular folder.

VBScript

Sub PostToFolderUsingExchange(sURL, sMailboxURL, sFrom, sSubject, sText)

  ' Assume type information has been imported into the scripting host.
  ' e.g. <reference object="CDO.Message"/> in .wsf script file.
  Set Msg = CreateObject("CDO.Message")
  Set conf = CreateObject("CDO.Configuration")
  Set Msg.Configuration = Conf

  With Conf.Fields
    .Item("http://schemas.microsoft.com/cdo/configuration/postusing")  = cdoPostUsingExchange
    .Item("http://schemas.microsoft.com/cdo/configuration/mailboxurl") = sMailboxURL
    .Item("http://schemas.microsoft.com/exchange/hardlinklist")        = Array(sURL)
    .Update
  End With
  With Msg
    .From     = sFrom
    .Subject  = sSubject
    .TextBody = sText
    .Post
  End With

End Sub

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Replying to Messages

You can easily reply to a message using the IMessage.Reply or IMessage.ReplyAll methods. These methods mimic the behavior of e-mail programs such as Microsoft® Outlook®.

Both methods return a new Message object reference. The difference in the two methods is that the ReplyAll method retains the original message's CC line in the new message. You must set the From property in the new message before you send the message.

If the http://schemas.microsoft.com/cdo/configuration/usemessageresponsetext field is set to True (VARIANT_TRUE), the TextBody of the reply method contains standard reply formatting. For example,

----Original Message----
From: "A Person" <person@microsoft.com>
Sent:  Sat, 23 Jan 1998 12:34:34 -0800
To:  "Another" <another@microsoft.com>
Subject: See this attached message

(body of the message here)

This message response text is localized into the language specified by using the http://schemas.microsoft.com/cdo/configuration/languagecode field in the Configuration object.

The Reply method puts the sender of the original message in the To property of the new message but removes all other recipients and any attachments. If the message contains a ReplyTo field, the Reply method sets the IMessage.To property to this ReplyTo field; otherwise, it sets the To property to the From field.

The ReplyAll method fills in the To line and removes any attachments as does the Reply method, but retains any recipients in the appropriate To or CC properties.

Visual Basic

' Reference to Microsoft ActiveX Data Objects 2.5 Library
' Reference to Microsoft CDO for Exchange 2000 Server Library
' ..
Sub ReplyToMessage(iMsg As CDO.Message)

    ' Assume we want to reply to all recipients.
    Dim iMsg2 As CDO.Message
    Set iMsg2 = iMsg.ReplyAll
    '   or Set iMsg2 = iMsg.Reply
    '      Set iMsg2 = iMsg.PostReply
    ' ..configure message object.
    '   Add any other recipients.
    iMsg2.TextBody = "I agree...please proceed." & vbCrLf & iMsg2.TextBody
    iMsg2.Send

End Sub

C++, IDL

#import "c:\program files\common files\system\ado\msado15.dll" no_namespace
#import "c:\program files\common files\microsoft shared\cdo\cdoex.dll" no_namespace

void replyToMessage( IMessagePtr& iMsg ) {

   // want to reply all

   IMessagePtr iMsg2;
   iMsg2 = iMsg->ReplyAll();
   // iMsg2 = iMsg->Reply();
   // iMsg2 = iMsg->PostReply();
   //     add any other recipients
   iMsg2->TextBody = "I agree...please proceed." + "\r\n" + iMsg2->TextBody;

   try {
      iMsg2->Send();
   }
   catch(_com_error e) {
      throw e;
   }
}

VBScript

Dim iDropDir
Dim iMsgs
Dim iMsg

Set iDropDir = CreateObject("CDO.DropDirectory")
Set iMsgs = iDropDir.GetMessages("c:\Inetpub\mailroot\Drop")
Set iMsg = iMsgs(1)

' want to reply all

Dim iMsg2
Set iMsg2 = iMsg.ReplyAll
' or Set iMsg2 = iMsg.Reply
'    Set iMsg2 = iMsg.PostReply
' ... configure message object
'     add any other recipients
iMsg2.TextBody = "I agree...please proceed." & vbCrLf & iMsg2.TextBody
iMsg2.Send

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Forwarding Messages

You can forward an existing message by using the IMessage.Forward method. The Forward method retains all the attachments from the original message, but does not set any recipients on the new message. You must set the To property in the new message before you send the message.

Visual Basic

' Reference to Microsoft ActiveX Data Objects 2.5 Library
' Reference to Microsoft CDO for Exchange 2000 Server Library
' ..
Sub ForwardMessage(iMsg As CDO.Message)

    Dim iMsg2 As CDO.Message
    Set iMsg2 = iMsg.Forward
    ' ..configure message object
    '   Add any other recipients
    iMsg2.TextBody = "You missed this:  " & vbCrLf & iMsg2.TextBody
    iMsg2.Send

End Sub

C++, IDL

#import "c:\program files\common files\system\ado\msado15.dll" no_namespace
#import "c:\program files\common files\microsoft shared\cdo\cdoex.dll" no_namespace

void forwardMessage( IMessagePtr& iMsg ) {

   // want to reply all

   IMessagePtr iMsg2;
   iMsg2 = iMsg->Forward();
   // iMsg2 = iMsg->Reply();
   // iMsg2 = iMsg->PostReply();
   //     add any other recipients
   iMsg2->TextBody = "I agree...please proceed." + "\r\n" + iMsg2->TextBody;

   try {
      iMsg2->Send();
   }
   catch(_com_error e) {
      throw e;
   }
}

VBScript

Dim iDropDir
Dim iMsgs
Dim iMsg

Set iDropDir = CreateObject("CDO.DropDirectory")
Set iMsgs = iDropDir.GetMessages("c:\\Inetpub\\mailroot\\Drop")
Set iMsg = iMsgs(1)

' want to reply all

Dim iMsg2
Set iMsg2 = iMsg.Forward
' ... configure message object
'     add any other recipients
iMsg2.TextBody = "You missed this: " & vbCrLf & iMsg2.TextBody
iMsg2.Send

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Extracting Embedded Messages

Use the IDataSource.OpenObject method to extract messages that are contained within other objects, such as Message or BodyPart objects, and move them into another Message object. This method is most useful when you want to extract an embedded message from another Message object's BodyPart hierarchy. The process is analogous to opening files in Microsoft® Word: the content in the opened file is copied from the disk into the open application. Embedded messages are contained in body parts with Content-Media-Type set to "message." When you encounter such a message in a body part, you can open it in the following way:

  1. Find the BodyPart (IBodyPart Interface) object that contains the embedded message. Call the Message object with the embedded message "message A." The urn:schemas:mailheader:content-type (Content-Type) for the body part should contain the "message" media type. The full content-type is normally "message/rfc822" for a fully embedded message (as opposed to partial or external-body subtypes).
  2. Create a new instance or use an existing instance of the Message Component Object Model (COM) class. Use this object to extract and hold the embedded message. Call this object Message B.
  3. Using the IDataSource interface on Message B, invoke its IDataSource.OpenObject method, passing the IBodyPart interface retrieved in step 1 as the first argument, and the string "IBodyPart" as the second argument. The string "IBodyPart" notifies the implementation that the passed interface reference is of type IBodyPart and therefore to expect a body part content stream to exist in the object.
  4. If the call is successful, the entire contents of the embedded message (including all attachments) in Message A are now present in Message B. In effect, Message B is a duplicate of Message A.
  5. If you want to alter the contents of the embedded message with changes you make in Message B, simply call the IDataSource.Save method. The changes are copied back to the source object from which you opened the message.

Visual Basic

' Reference to Microsoft ActiveX Data Objects 2.5 Library
' Reference to Microsoft CDO for Exchange 2000 Server Library
' ..
Function ExtractMessage(iBp As IBodyPart) As Message
    Dim iMsg As New CDO.Message
    Dim iDsrc As IDataSource
    Set iDsrc = iMsg
    iDsrc.OpenObject iBp, "IBodyPart"
    Set ExtractMessage = iMsg
End Function

C++, IDL

#import "c:\program files\common files\system\ado\msado15.dll" no_namespace
#import "c:\program files\common files\microsoft shared\cdo\cdoex.dll" no_namespace
// ...
IMessagePtr ExtractMessage(IBodyPartPtr iBp)
{
      IMessagePtr iMsg(__uuidof(Message));
      IDataSourcePtr iDsrc;
      iDsrc = iMsg;

      try
      {
            iDsrc->OpenObject(iBp,_bstr_t("IBodyPart"));
      }
      catch(_com_error error)
      {
            throw error;
      }
      return iMsg;
}

VBScript

Function ExtractMessage(iBp As IBodyPart) As Message
    Dim iMsg
    Set iMsg = CreateObject("CDO.Message")
    Dim iDsrc
    Set iDsrc = iMsg.DataSource
    iDsrc.OpenObject iBp, "IBodyPart"
    Set ExtractMessage = iMsg
End Function

Related Topics

  • urn:schemas:mailheader:content-type Field

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Embedding a Message

You can use the IDataSource.SaveToObject method to "copy" an entire Message object into another Message object. This is most useful when you want to embed the message into another as a body part. If you embed Message A into Message B, Message B then contains all of message A in its Multipurpose Internet Mail Extensions (MIME) hierarchy as a body part with Content-Type "message/rfc822."

To embed one message in another, perform the following steps:

  1. Obtain an IMessage object reference on the Message object containing the message you want to embed.
  2. Obtain the IDataSource interface on that object.
  3. Obtain the IBodyPart object reference on the BodyPart object within the body part hierarchy of the Message object in which you want to embed the message.
  4. Call IDataSource.SaveToObject on the first Message object, passing the IBodyPart object reference as the first parameter, and the string "IBodyPart" as the second. This step embeds the message and creates a binding between the Message and BodyPart objects.
  5. If you make changes to the message, you can save them by re-embedding the message. Because the Message and BodyPart objects are currently bound, you need only call IDataSource.Save.

Visual Basic

' Reference to Microsoft ActiveX Data Objects 2.5 Library
' Reference to Microsoft CDO for Exchange 2000 Server Library
' ..
Sub EmbedMessage(iMsg As CDO.Message, iBp As IBodyPart)
    Dim iDsrc As IDataSource
    Set iDsrc = iMsg
    iDsrc.SaveToObject iBp, "IBodyPart"
End Sub

C++, IDL

#import "c:\program files\common files\system\ado\msado15.dll" no_namespace
#import "c:\program files\common files\microsoft shared\cdo\cdoex.dll" no_namespace
// ...
void EmbedMessage( IMessagePtr& iMsg, IBodyPartPtr& iBp)
{
      IDataSourcePtr iDsrc;
      iDsrc = iMsg;

      try
      {
            iDsrc->SaveToObject(iBp,_bstr_t("IBodyPart"));
      }
      catch(_com_error error)
      {
            throw error;
      }
}

VBScript

Sub EmbedMessage(iMsg As CDO.Message, iBp As IBodyPart)
    Dim iDsrc
    Set iDsrc = iMsg.DataSource
    iDsrc.SaveToObject iBp, "IBodyPart"
End Sub

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Loading Messages from Within ADO Stream Objects

To load a serialized message into a CDO Message object from an Microsoft® ActiveX® Data Objects (ADO) Stream object, perform the following steps:

  1. Retrieve the IDataSource interface on the Message object.
  2. Create or otherwise obtain a _Stream object reference on an ADO Stream object.
  3. Use the IDataSource interface on the Message object to call OpenObject. Pass the _Stream object reference as the first argument, and the string "_Stream" as the second.

Visual Basic

' Reference to Microsoft ActiveX Data Objects 2.5 Library
' Reference to Microsoft CDO for Exchange 2000 Server Library
' ..
Function LoadMessageFromFile(Path As String) As Message
    Dim Stm As New Stream
    Stm.Open
    Stm.LoadFromFile Path
    Dim iMsg As New CDO.Message
    Dim iDsrc As IDataSource
    Set iDsrc = iMsg
    iDsrc.OpenObject Stm, "_Stream"
    Set LoadMessageFromFile = iMsg
End Function

C++, IDL

#import "c:\program files\common files\system\ado\msado15.dll" no_namespace
#import "c:\program files\common files\microsoft shared\cdo\cdoex.dll" no_namespace
// ...
IMessagePtr Load_Message_from_File(_bstr_t path)
{
      /*
      ** This example shows a common use of the ADO Stream
      ** object with CDO, namely, opening a serialized
      ** message from a file on disk and loading it into
      ** a CDO Message object.
      **/

      _StreamPtr  pStm(__uuidof(Stream));
      _variant_t varOptional(DISP_E_PARAMNOTFOUND,VT_ERROR);
      try {
            pStm->raw_Open(varOptional, adModeUnknown,
adOpenStreamUnspecified,NULL,NULL);
            pStm->LoadFromFile(path);
      }
      catch(_com_error e)
      {
            throw e;
      }

      IMessagePtr iMsg(__uuidof(Message));
      IDataSourcePtr iDsrc;
      iDsrc = iMsg;

      try {
            iDsrc->OpenObject(pStm,_bstr_t("_Stream"));
      }
      catch(_com_error e)
      {
            throw e;
      }

      // ....

      return iMsg;
}

VBScript

Function LoadMessageFromFile(Path) As Message
    Dim Stm
    Set Stm = CreateObject("ADODB.Stream")
    Stm.Open
    Stm.LoadFromFile Path
    Dim iMsg
    Set iMsg = CreateObject("CDO.Message")
    Dim iDsrc
    Set iDsrc = iMsg
    iDsrc.OpenObject Stm, "_Stream"
    Set LoadMessageFromFile = iMsg
End Function

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Saving Messages into ADO Stream Objects

To save a serialized message from a CDO Message object to a Microsoft® ActiveX® Data Objects (ADO) Stream object, perform the following steps:

  1. Retrieve the IDataSource interface on the Message object.
  2. Create or otherwise obtain a _Stream object reference on an ADO Stream object.
  3. Use the IDataSource interface on the Message object to call OpenObject. Pass the _Stream object reference as the first argument, and the string "_Stream" as the second.

Visual Basic

' Reference to Microsoft ActiveX Data Objects 2.5 Library
' Reference to Microsoft CDO for Exchange 2000 Server Library
' ..
Sub SaveMessageToFile(iMsg As CDO.Message, Filepath As String)
    Dim Stm As New Stream
    Stm.Open
    Stm.Type = adTypeText
    Stm.Charset = "US-ASCII"

    Dim iDsrc As IDataSource
    Set iDsrc = iMsg
    iDsrc.SaveToObject Stm, "_Stream"

    Stm.SaveToFile Filepath, adSaveCreateOverWrite

End Sub

C++, IDL

#import "c:\program files\common files\system\ado\msado15.dll" no_namespace
#import "c:\program files\common files\microsoft shared\cdo\cdoex.dll" no_namespace
// ...
void Save_Message_to_File(IMessagePtr iMsg, bstr_t filename)
{
      /*
      ** This example shows a common use of the ADO Stream
      ** object with CDO, namely, saving a serialized
      ** message to disk using an ADO Stream object.
      **/
      _StreamPtr  pStm(__uuidof(Stream));
      IDataSourcePtr iDsrc;
      iDsrc = iMsg;

      _variant_t varOptional(DISP_E_PARAMNOTFOUND,VT_ERROR);
      pStm->raw_Open(varOptional, adModeUnknown,
adOpenStreamUnspecified,NULL,NULL);
      pStm->Type = adTypeText;
      pStm->Charset = "US-ASCII"; // apparently, we need this!
      try
      {
            iDsrc->SaveToObject(pStm,_bstr_t("_Stream"));
      }
      catch(_com_error error)
      {
            throw error;
      }

      try {
            pStm->SaveToFile(filename,adSaveCreateOverWrite);
      }
      catch(_com_error e)
      {
            throw e;
      }
}

VBScript

Sub SaveMessageToFile(iMsg, Filepath)
    Dim Stm
    Set Stm = CreateObject("ADODB.Stream")
    Stm.Open
    Stm.Type = adTypeText ' 2
    Stm.Charset = "US-ASCII"

    Dim iDsrc
    Set iDsrc = iMsg.DataSource
    iDsrc.SaveToObject Stm, "_Stream"

    Stm.SaveToFile Filepath, adSaveCreateOverWrite

End Sub

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Listing Inbox Contents Using ADO

The following example demonstrates how to create a common item listing of a user's inbox. This list, or "view," is normally presented when a user selects a folder in their mailbox that contains messages.

Visual Basic

' Reference to Microsoft ActiveX Data Objects 2.5 Library
' Reference to Microsoft CDO for Exchange 2000 Server Library
' ..
Dim Rec   As New ADODB.Record
Dim Rs    As New ADODB.Recordset
Dim strURLInbox As String

strURLMailbox = "file://./backofficestorage/microsoft.com/MBX/user1/"
Rec.Open strURLMailbox
sURLInbox = Rec.Fields("urn:schemas:httpmail:inbox")
Rec.Open sURLInbox, Rec.ActiveConnection

Dim strView As String
strView = "select " _
& "  ""DAV:href""" _
& ", ""DAV:content-class""" _
& ", ""urn:schemas:httpmail:datereceived""" _
& ", ""DAV:isfolder""" _
& ", ""DAV:getcontentlength""" _
& ", ""urn:schemas:httpmail:from""" _
& ", ""urn:schemas:httpmail:subject""" _
& ", ""urn:schemas:mailheader:importance""" _
& ", ""urn:schemas:httpmail:hasattachment""" _
& ", ""urn:schemas:httpmail:read""" _
& " from scope ('shallow traversal of """ _
& strURLInbox & """') " _
& " WHERE ""DAV:isfolder"" = false AND ""DAV:ishidden"" = false" _
& " ORDER BY ""urn:schemas:httpmail:datereceived"" DESC"

Rs.Open strView, Rec.ActiveConnection

If Rs.RecordCount = 0 Then
  ' no items in inbox
Else
  Rs.MoveFirst
  While Not Rs.EOF
   ' render view data here
     Rs.MoveNext
  Wend
End If

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Example Code

This section contains sample code in Microsoft® Visual Basic® Scripting Edition (VBScript), Visual Basic, and Microsoft® Visual C++® that shows how to send mail, include attachments with messages, and sort the inbox.

Sending Mail Using CDOEX and Exchange 2000 Server

Sorting the Inbox Based on Received Time Using ADO

Sending SMTP Mail by the Pickup Directory Using CDOSYS (VBScript)

Sending SMTP Mail by Port 25 Using CDOSYS (VBScript)

Sending a Web Page by SMTP Mail Using CDOSYS

Listing Unread Messages in a Folder Using ADO

Sending a Message Using CDOEX

Sending SMTP Mail by the Pickup Directory Using CDOSYS (Visual Basic)

Sending SMTP Mail by Port 25 Using CDOSYS (Visual Basic)

Posting a Message to an NNTP Newsgroup

Sending a Message (with Attachments) with OLEDB and CDOEX

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Sending Mail Using CDOEX and Exchange 2000 Server

VBScript

'Send Mail using CDOEx and Exchange 2000 Server
'
'1) Create a folder named "test" under inetpub/wwwroot.
'2) Save this file in that folder as NewMail.asp
'3) Make the changes to the file i.e. Change the iMsg.From line to reflect your mailbox.
'4) Save the file.
'5) open internet service manager and browse to the "test"  folder
'6) right click and go to properties
'7) go to the "Directory Security" tab.
'8) Click on "Edit" button next to the "handshake" icon
'9) Uncheck "Anonymous Access"
'10) check the "Digest Authentication" and "Integrated windows authentication" boxes
'11) click ok
'12) click ok
'13) load the asp in your browser.
'14) Fill in the fields on the html form
'15) click "submit" to send mail.
-->

<%@ Language=VBScript %>
<%

submit = Request.Form.Item("B1")

if submit = "Send" then
Dim iMsg
'Create the message object
Set iMsg = CreateObject("CDO.Message")
Dim iConf
'Create the configuration object
Set iConf = CreateObject("CDO.Configuration")
Dim Flds
'Set the fields of the configuration object to send using exchange server
Set Flds = iConf.Fields
Flds( "http://schemas.microsoft.com/cdo/configuration/sendusing") = 3
Flds.Update
'Set the message to,from,subject,body properties.
Set iMsg.Configuration = iConf
iMsg.To = Request.Form.Item("Text1")
iMsg.From = "someone@someplace.com"
iMsg.Subject = Request.Form.Item("Text3")
iMsg.TextBody = Request.Form.Item("TextArea1")
iMsg.Send

end if

%>

<html>
<head>
<meta NAME="GENERATOR" Content="Microsoft Visual Studio 6.0">
</head>

<body >
<% if submit = "Send" then %>

Mail Sent

<%else%>

<form name="mnFrm" method="post" action="NewMail.asp">
<P>
<base target="_top">
<TABLE >
<tr>
<TD> To </TD>
<TD><INPUT name=Text1 size=58 style="HEIGHT: 22px; WIDTH: 500px"></TD></TR>
<TR>

<TD><LABEL> Subject </LABEL></TD>
<TD><INPUT border=0 name=Text3 size=58
style="HEIGHT: 22px; WIDTH: 500px"></TD></TR>
<TR>
<TD vAlign=top><LABEL> Body </LABEL></TD>
<TD><TEXTAREA cols=63 name=TextArea1 rows=30 style="BACKGROUND-COLOR: white; HEIGHT: 165px; WIDTH: 590px"></TEXTAREA>

<P></P>
<P><BR></P></TD></TR></TABLE><INPUT name=B1 type=submit value="Send"></P>
</form>
<%end if %>
</body>
</html>
<!--

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Sorting the Inbox Based on Received Time Using ADO

VBScript

Note The following example uses a file URL with the Exchange OLE DB (ExOLEDB) provider. The ExOLEDB provider also supports the HTTP URL scheme. Using the HTTP URL scheme allows both client and server applications to use a single URL scheme.
'Sorting the Inbox based on received time using ADO
-->

<!--
Build Instructions:
Save this file in a newly created virtual dir under wwwroot
-->
<%@ Language=VBScript %>
<HTML>
<HEAD>
<META NAME="GENERATOR" Content="Microsoft Visual Studio 6.0">
</HEAD>
<BODY>
<%
Dim Rec
Dim Rs
Dim strURL
Dim strQ
Dim strSubj
Dim DomainName
Dim strLocalPath

Set Rec = CreateObject("ADODB.Record")
Set Rs = CreateObject("ADODB.Recordset")

' set your own values to these variables:
DomainName = "somedomain.microsoft.com"
strLocalPath = "MBX/User1/inbox"

strURL = "file://./backofficestorage/" & DomainName & "/" & strLocalPath
Rec.Open strURL

' build the query string
strQ = "select "
strQ = strQ & " ""urn:schemas:mailheader:date"""
strQ = strQ & ", ""urn:schemas:mailheader:sender"""
strQ = strQ & ", ""urn:schemas:mailheader:subject"""
strQ = strQ & ", ""urn:schemas:mailheader:received"""
strQ = strQ & ", ""DAV:contentclass"""
strQ = strQ & ", ""DAV:href"""
strQ = strQ & " from scope ('shallow traversal of "
strQ = strQ & Chr(34) & strURL & Chr(34) & "') "

' sort received time in descending order(can also use ascending)
strQ = strQ & " ORDER BY ""urn:schemas:mailheader:received"" DESC"

Rs.Open strQ, Rec.ActiveConnection

Rs.MoveFirst

' display all of the sorted messages
Do Until Rs.EOF
Response.Write "<b>Subject:</b><br>"
Response.Write Rs.Fields("urn:schemas:mailheader:subject").Value & "<br>"
Response.Write "<b>Date Sent:</b><br>"
Response.Write Rs.Fields("urn:schemas:mailheader:date").Value & "<br>"
Response.Write "<b>Date Received:</b><br>"
Response.Write Rs.Fields("urn:schemas:mailheader:date").Value & "<br>"
Response.Write "<b>Content-Class:</b><br>"
Response.Write Rs.Fields("DAV:contentclass").Value & "<br>"
Response.Write "<b>URL:</b><br>"
Response.Write Rs.Fields("DAV:href").Value & "<br>"
Response.Write "</p>"
Rs.MoveNext
Loop

Rs.Close
Rec.Close
%>
<P> </P>

</BODY>
</HTML>
<!--

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Sending SMTP Mail by the Pickup Directory Using CDOSYS

VBScript

'Sending SMTP mail via the pickup directory using CDOSYS
-->

<!--
'This ASP page uses CDOSYS to send SMTP mail using the cdoSendUsingPickup option.  The e-mail is created in the pickup directory of the local SMTP server and delivery is handled by the local SMTP service.
-->

<%@ Language=VBScript %>
<HTML>
<HEAD>
<META NAME="GENERATOR" Content="Microsoft Visual Studio 6.0">
</HEAD>
<BODY>
<%
'Send using the Pickup directory on the IIS server
Dim iMsg
Dim iConf
Dim Flds
Dim strHTML

Const cdoSendUsingPickup = 1

set iMsg = CreateObject("CDO.Message")
set iConf = CreateObject("CDO.Configuration")

' set the CDOSYS configuration fields to use the SMTP service pickup directory
Set Flds = iConf.Fields
With Flds
'.Item("cdoSendUsingMethod") = cdoSendUsingPickup
.Item("http://schemas.microsoft.com/cdo/configuration/sendusing") = cdoSendUsingPickup
.Update
End With

' build HTML for message body
strHTML = "<HTML>"
strHTML = strHTML & "<HEAD>"
strHTML = strHTML & "<BODY>"
strHTML = strHTML & "<b> This is the test HTML message body</b></br>"
strHTML = strHTML & "</BODY>"
strHTML = strHTML & "</HTML>"

' apply settings to the message
With iMsg
Set .Configuration = iConf
.To = "nrnoble@Microsoft.com"
.From = "nrnoble@Microsoft.com"
.Subject = "This is a test CDOSYS message (Pickup directory)"
.HTMLBody = strHTML
.Send
End With

' cleanup of variables
Set iMsg = Nothing
Set iConf = Nothing
Set Flds = Nothing

%>
<P> </P>

</BODY>
</HTML>
<!--

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Sending SMTP Mail by Port 25 Using CDOSYS

VBScript

-->

<!--
'Sending SMTP mail via port 25 using CDOSYS
'This ASP page uses CDOSYS to send SMTP mail using port 25 of the SMTP server that is set.  The e-mail delivery is handled by the SMTP server that is set in the configuration object.
-->

<%@ Language=VBScript %>
<HTML>
<HEAD>
<META NAME="GENERATOR" Content="Microsoft Visual Studio 6.0">
</HEAD>
<BODY>
<%
' send by connecting to port 25 of the SMTP server
Dim iMsg
Dim iConf
Dim Flds
Dim strHTML
Dim strSmartHost

Const cdoSendUsingPort = 2
StrSmartHost = "smarthost"

set iMsg = CreateObject("CDO.Message")
set iConf = CreateObject("CDO.Configuration")

Set Flds = iConf.Fields

' set the CDOSYS configuration fields to use port 25 on the SMTP server

With Flds
.Item("http://schemas.microsoft.com/cdo/configuration/sendusing") = cdoSendUsingPort
.Item("http://schemas.microsoft.com/cdo/configuration/smtpserver") = strSmartHost
.Item("http://schemas.microsoft.com/cdo/configuration/smtpconnectiontimeout") = 10
.Update
End With

' build HTML for message body
strHTML = "<HTML>"
strHTML = strHTML & "<HEAD>"
strHTML = strHTML & "<BODY>"
strHTML = strHTML & "<b> This is the test HTML message body</b></br>"
strHTML = strHTML & "</BODY>"
strHTML = strHTML & "</HTML>"

' apply the settings to the message
With iMsg
Set .Configuration = iConf
.To = "nrnoble@Microsoft.com"
.From = "nrnoble@Microsoft.com"
.Subject = "This is a test CDOSYS message (Sent via Port 25)"
.HTMLBody = strHTML
.Send
End With

' cleanup of variables
Set iMsg = Nothing
Set iConf = Nothing
Set Flds = Nothing

%>
<P> </P>

</BODY>
</HTML>
<!--

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Sending a Web Page by SMTP Mail Using CDOSYS

VBScript

'Sending a webpage via SMTP mail using CDOSYS
-->

<!--
'This ASP uses the CreateMHTMLBody method of the iMsg object to send a web page to another SMTP recipient using the CDOSYS library.

Build Instructions:
Add the above ASP file to a new virtual directory under the wwwroot.
Platinum should not be installed on the Windows 2000 server. The SMTP components
do need to be installed during the Windows 2000 setup.
-->

<%@ Language=VBScript %>

<%

' Reference to Microsoft ActiveX Data Objects 2.5 Library
' Reference to Microsoft CDO for Windows 2000 Library

Dim iMsg
Dim iConf
Dim Flds

set iMsg = CreateObject("CDO.Message")
set iConf = CreateObject("CDO.Configuration")

' set the configuration fields
Set Flds = iConf.Fields

' set the proxy server to be used
' TODO: Set "someproxy:80" to the name of your proxyserver
Flds("http://schemas.microsoft.com/cdo/configuration/urlproxyserver") = "someproxy:80"

' set if this is a local server
Flds("http://schemas.microsoft.com/cdo/configuration/urlproxybypass") = "<local>"

' set option to retrieve the latest content directly from the server
Flds("http://schemas.microsoft.com/cdo/configuration/urlgetlatestversion") = True
Flds.Update

' set the message properties
With iMsg

Set .Configuration = iConf
' create the MIME representation of the web page in the message
' TODO: Change the .To and .From fields to valid e-mail addresses
.CreateMHTMLBody "http://www.microsoft.com"
.To = "<valid address>@microsoft.com"
.From = "<valid address>@microsoft.com"
.Subject = "Sample MHTML message..."
.Send
End With

%>
<!--

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Listing Unread Messages in a Folder Using ADO

VBScript

Note The following example uses a file URL with the Exchange OLE DB (ExOLEDB) provider. The ExOLEDB provider also supports the HTTP URL scheme. Using the HTTP URL scheme allows both client and server applications to use a single URL scheme.
'Listing unread messages in a folder using ADO
-->

<!--
'Listing unread messages in a folder using ADO
'This ASP page loops through all of the messages in the inbox and outputs the unread messages in a HTML table.
-->

<%@ Language=VBScript %>
<%
Dim Rec
Dim Rs
Dim strURL
Dim strQ
Dim strSubj
Dim DomainName
Dim strLocalPath
Dim UnreadCount

Set Rec = CreateObject("ADODB.Record")
Set Rs = CreateObject("ADODB.Recordset")

' time can be changed for folders with more messages
Session.Timeout = 10

' set your own values to these variables:
DomainName = "nrnobledom2"

UserID ="User1"
PSW ="pass"

strLocalPath = "MBX/" & UserID & "/inbox"

strURL = "file://./backofficestorage/" & DomainName & "/" & strLocalPath
Response.Write "strURL= " & strURL

Rec.Open strURL,,,,,UserID,PSW

' build the SQL query for the messages
strQ = "select "
strQ = strQ & " ""urn:schemas:mailheader:date"""
strQ = strQ & ", ""urn:schemas:httpmail:to"""
strQ = strQ & ", ""urn:schemas:httpmail:from"""
strQ = strQ & ", ""urn:schemas:mailheader:subject"""
strQ = strQ & ", ""urn:schemas:mailheader:received"""
strQ = strQ & ", ""urn:schemas:httpmail:read"""
strQ = strQ & ", ""DAV:contentclass"""
strQ = strQ & ", ""DAV:href"""
strQ = strQ & " from scope ('shallow traversal of "
strQ = strQ & Chr(34) & strURL & Chr(34) & "') "
strQ = strQ & " WHERE ""urn:schemas:httpmail:read"" = false"

' open the recordset
Rs.Open strQ, Rec.ActiveConnection

Rs.MoveFirst
Unreadcount = 0

' loop through all of the messages in the recordset and format for browser
Do Until Rs.EOF
Response.Write "<TABLE BORDER=2 cellpadding=2 cellspacing=2 width='100%'><TR>"
Response.Write "<tr><td><b>From: </b></td>"
Response.Write "<td>" & Rs.Fields("urn:schemas:httpmail:from").Value & "</td></tr>"
Response.Write "<tr><td><b>To: </b></td>"
Response.Write "<td>" & Rs.Fields("urn:schemas:httpmail:to").Value & "</td></tr>"
Response.Write "<tr><td><b>Subject: </b></td>"
Response.Write "<td>" & Rs.Fields("urn:schemas:mailheader:subject").Value & "</td></tr>"
Response.Write "<tr><td><b>Date Sent: </b></td>"
Response.Write "<td>" & Rs.Fields("urn:schemas:mailheader:date").Value & "</td></tr>"
Response.Write "<tr><td><b>Date Received: </b></td>"
Response.Write "<td>" & Rs.Fields("urn:schemas:mailheader:date").Value & "</td></tr>"
Response.Write "<tr><td><b>Content-Class: </b></td>"
Response.Write "<td>" & Rs.Fields("DAV:contentclass").Value & "</td></tr>"
Response.Write "<tr><td><b>URL: </b></td>"
Response.Write "<td>" & Rs.Fields("DAV:href").Value & "</td></tr>"
Response.Write "</p>"
unreadcount = unreadcount + 1
Rs.MoveNext
Response.Write "<tr><td height=10></tr></td><tr><td height=10></tr></td>"
Response.Write "</TABLE><br>"
Loop

' close the record and recordset
Rs.Close
Rec.Close

Response.Write "<hr size=5><b>Total unread messages: </b>" & unreadcount

%>
<!--

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Sending a Message Using CDOEX

Visual Basic

'Sending a Message via CDO
'Reference the project with CDO for Exchage 2000 and ADO 2.5 libraries

Private Sub Main()
'Sending Mail Message Using Exchange Server

Dim oMessage As CDO.Message
'Create a Message Object
Set oMessage = CreateObject("CDO.Message")

With oMessage
'Set the properties
.To = InputBox("Enter the recipient's e-mail address")
.From = InputBox("Enter the sender's e-mail address")
.TextBody = "This is a sample Body" 'Your TextBody
.Subject = "This is a sample Subject" 'Your Subject
.Configuration.Fields("CdoSendUsing") = cdoSendUsingExchange 'Using Exchange Server
.Configuration.Fields.Update
.AddAttachment ("c:\file1.txt")
.CreateMHTMLBody "http://www.microsoft.com"
.Send
End With

End Sub

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Sending SMTP Mail by the Pickup Directory Using CDOSYS

Visual Basic

'Sending SMTP mail via the pickup directory using CDOSYS
'Send using the Pickup directory on the IIS server

Private Sub sendmsg(strTo As String, strFrom As String)

Dim iMsg As New CDO.Message
Dim iConf As New CDO.Configuration
Dim Flds As ADODB.Fields
Dim strHTML

Set Flds = iConf.Fields
With Flds
.Item(cdoSendUsingMethod) = cdoSendUsingPickup
.Update
End With

' Build HTML for message body
strHTML = "<HTML>"
strHTML = strHTML & "<HEAD>"
strHTML = strHTML & "<BODY>"
strHTML = strHTML & "<b> This is the test HTML message body</b></br>"
strHTML = strHTML & "</BODY>"
strHTML = strHTML & "</HTML>"

With iMsg
Set .Configuration = iConf
.To = strTo
.From = strFrom
.Subject = "This is a test CDOSYS message (Pickup directory)"
.HTMLBody = strHTML

.Send
End With

' cleanup of variables
Set iMsg = Nothing
Set iConf = Nothing
Set Flds = Nothing

End Sub

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Sending SMTP Mail by Port 25 Using CDOSYS

Visual Basic

'Sending SMTP mail via port 25 using CDOSYS
'This VB sample uses CDOSYS to send SMTP mail using the cdoSendUsingPort option and specifying a SMTP host.

Private Sub SendMessage(strTo As String, strFrom As String)

'Send using the Port on a SMTP server
Dim iMsg As New CDO.Message
Dim iConf As New CDO.Configuration
Dim Flds As ADODB.Fields
Dim strHTML

Set Flds = iConf.Fields

With Flds
    .Item(cdoSendUsingMethod) = cdoSendUsingPort
    .Item(cdoSMTPServer) = "smarthost"
    'Use SSL to connect to the SMTP server:
    '.Item(cdoSMTPUseSSL) = True
    .Item(cdoSMTPConnectionTimeout) = 10
    .Update
End With

' Build HTML for message body
strHTML = "<HTML>"
strHTML = strHTML & "<HEAD>"
strHTML = strHTML & "<BODY>"
strHTML = strHTML & "<b> This is the test HTML message body</b></br>"
strHTML = strHTML & "</BODY>"
strHTML = strHTML & "</HTML>"

With iMsg
    Set .Configuration = iConf
    .To = strTo
    .From = strFrom
    .Subject = "This is a test CDOSYS message (Sent by Port)"
    .HTMLBody = strHTML
    '.TextBody = "This is the text body of the message..."

    .Send
End With

' cleanup of variables
Set iMsg = Nothing
Set iConf = Nothing
Set Flds = Nothing

End Sub

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Posting a Message to an NNTP Newsgroup

Visual Basic

Private Sub POST_NEWS_MESSAGE()
Dim Msg As New CDO.Message
Dim Cfg As New CDO.Configuration

Cfg.Fields("http://schemas.microsoft.com/cdo/configuration/postusing").Value = 2
Cfg.Fields("http://schemas.microsoft.com/cdo/configuration/nntpserver").Value = "yournntpserver"

Cfg.Fields.Update
Set Msg.Configuration = Cfg

Msg.Subject = "Hello"
Msg.From = "user1@yourdomain.com"
Msg.Newsgroups = "yournewsgroup"
Msg.Post

End Sub

Note You must set the Subject, From, and Newsgroups properties for a Message object, or the Post method generates an error.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Sending a Message (with Attachments) with OLEDB and CDOEX

Visual C++

Note The following example uses a file URL with the Exchange OLE DB (ExOLEDB) provider. The ExOLEDB provider also supports the HTTP URL scheme. Using the HTTP URL scheme allows both client and server applications to use a single URL scheme.
//Sending a Message (w/Attachments) using OLEDB and CDOEx
#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <activeds.h>

#import <msado15.dll> no_namespace rename("EOF","adoEOF")
#import <cdoex.dll> no_namespace

struct StartOle
{
   StartOle() { CoInitialize(NULL); }
   ~StartOle() { CoUninitialize(); }
} _inst_StartOle;

HRESULT GetDomainName(BSTR* bstrDomainName);

void main(void)
{

   LPSTR lpUser = "User1";
   LPSTR  lpAttachment ="C:\\hello.txt";

   _ConnectionPtr conn(_uuidof(Connection));
   _RecordsetPtr MyInbox(_uuidof(Recordset));

   HRESULT hRes = NULL;
   BSTR bstrDomainDNSName;

   // Get your Domain Name.
   hRes = GetDomainName(&bstrDomainDNSName);

   try
   {
      conn->Provider = "Exoledb.DataSource";

      _bstr_t strConnString = "file://./backofficestorage/" + (_bstr_t)bstrDomainDNSName + "/MBX/" + (_bstr_t)lpUser + "/Inbox";
      printf(strConnString);

      hRes = conn->Open(strConnString,"","",0);

      if (conn->State == adStateOpen)
         printf("Connection Opened!\n");
      else
         printf("Connection failed!\n");

      _bstr_t  strQ = "select * from scope ('shallow traversal of \""+ strConnString + "\"') " ;

      hRes = MyInbox->Open(strQ,conn->ConnectionString,adOpenForwardOnly,adLockReadOnly,0);

      IConfigurationPtr iConf( __uuidof(Configuration));

      FieldsPtr Flds = iConf->GetFields();
      FieldPtr Fld = Flds->GetItem("http://schemas.microsoft.com/cdo/configuration/sendusing");
       Fld->Value = "cdoSendUsingExchange";

      printf("Configuration object created\n");

      IMessagePtr iMsg(__uuidof(Message));

      iMsg->put_Configuration(iConf);
      iMsg->put_From("User1@" + (_bstr_t)bstrDomainDNSName);
      iMsg->put_To("User2@" + (_bstr_t)bstrDomainDNSName);
      iMsg->put_Subject(L"Test Subject");
      iMsg->put_TextBody(L"Test Body");
      iMsg->AddAttachment( lpAttachment,"","");
      iMsg->Send();
      printf("Mail Sent\n");
   }
   catch(...)
   {
      printf("Something failed!\n");
   }
   conn = NULL;
}

/*******************************************
// GetDomainName
//
// Params: [out] BSTR * bstrDomainName
// Output: HRESULT
// Purpose: Retrieve the Domain DNS name.
********************************************/
HRESULT GetDomainName(BSTR * bstrDomainName)
{
   HRESULT hr = S_OK;
   IADsADSystemInfo *pADsys;

   hr = CoCreateInstance(   CLSID_ADSystemInfo,
                     NULL,
                     CLSCTX_INPROC_SERVER,
                     IID_IADsADSystemInfo,
                     (void**)&pADsys);
   hr = pADsys->get_DomainDNSName(bstrDomainName);

   if (pADsys)
      pADsys->Release();
   return hr;
}

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Related Topics

This section does not currently contain any topics. Information will be provided here as it becomes available.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Appendixes

The topics in this section describe MIME Encapsulation of Aggregate HTML Documents (MHTML), MIME, Internet Messages, Simple Mail Transport Protocol (SMTP), and SMTP/ NNTP Transport Event Sinks.

MIME Encapsulation of Aggregate HTML Documents (MHTML)

MIME Extensions to Internet Mail

Internet Messages and SMTP

SMTP/NNTP Transport Event Sinks with CDO

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


MIME Encapsulation of Aggregate HTML Documents (MHTML)

MIME Encapsulation of Aggregate HTML Documents (MHTML) is an Internet standard that defines the MIME structure used to send HTML content in message bodies along with those resources referenced from within the HTML. The HyperText Markup Language (HTML) is a markup language used to create documents that are portable between various platforms. One of its key features is the ability to render a document composed of separate resources, such as images, sound files, cascading style sheets, and Microsoft® ActiveX® objects, inline with the marked up text. Many e-mail clients, such as Microsoft® Outlook® Express, are capable of displaying HTML pages just as they would appear in a Web browser. As e-mail content, such HTML documents usually include links to other resources that are available on the network. The HTML author identifies these resources for inclusion in the page by using relative or absolute URLs as attributes within HTML markup elements.

In many cases, it is desirable to include external resources referenced by the HTML document in the message body itself. The MHTML specification provides the architecture used to encapsulate referenced resources within the message body. This allows the e-mail client to construct and render the page without retrieving these resources directly over the network.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Key Concepts of MHTML

As a document format for MIME e-mail, HTML has been available for years in the form of the text/HTML content type. However, the richness of HTML as an interoperable e-mail format can be achieved only through the use of the MIME multipart/related content type. This content type allows the message to contain an HTML page and other resources, such as pictures and sound, included directly in the MIME hierarchy of the message. This data can be referenced through links from the HTML content and used to complete the rendering of the document. This usage allows the recipient to resolve all the links "locally" — that is, without having to use the network.

MIME Encapsulation of Aggregate HTML Documents (MHTML) defines the naming of objects that are normally referred to by URLs and the means of aggregating resources that go together. Two MIME headers, Content-Location and Content-Base, are defined in order to resolve references to other content stored locally in related body parts. Content-Base gives an absolute URL base, or "starting point", for relative URLs that appear in other MIME headers and in HTML documents that do not contain any BASE HTML elements. Content-Location specifies the URL that corresponds to the content of the body part that contains this header.

The following example shows an MHTML message with a relative reference to an embedded Graphics Interchange Format (GIF).

From: user1@microsoft.com
To: user2@microsoft.com
Subject: An example
Mime-Version: 1.0
Content-Base: http://www.microsoft.com
Content-Type: Multipart/related; boundary="boundary-example-1";type=Text/HTML

--boundary-example-1
Content-Type: Text/HTML; charset=ISO-8859-1
Content-Transfer-Encoding: QUOTED-PRINTABLE

... text of the HTML document, which might contain a hyperlink
to the other body part, for example through a statement such as:
<IMG SRC="/images/ie5.gif" ALT="Internet Explorer logo">
Example of a copyright sign encoded with Quoted-Printable: =A9
Example of a copyright sign mapped onto HTML markup: &#168;

--boundary-example-1
Content-Location: /images/ie5.gif
Content-Type: IMAGE/GIF
Content-Transfer-Encoding: BASE64

AAAFFDDlhGAGgAPEAAP/////ZRaCgoAAAACH+PUNvcHlyaWdodCAoQykgMTk5
NSBJRVRGLiBVbmF1dGhvcml6ZWQgZHVwbGljYXRpb24gcHJvaGliaXRlZC4A
etc...

--boundary-example-1 -

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


CDO Support for MHTML

CDO Component Object Model (COM) components provide native support for MIME formatted content. Because MIME Encapsulation of Aggregate HTML Documents (MHTML) is based on MIME, the CDO object model can be used to create MHTML formatted messages. To facilitate the construction of MHTML formatted messages, the IMessage interface defines two methods, IMessage.CreateMHTMLBody and IMessage.AddRelatedBodyPart. The CreateMHTMLBody method can construct the entire multipart/related MIME structure for you; you only need to specify the URL to the page you want to add to the message. The appropriate multipart/related body part hierarchy is automatically created, complete with the necessary body part headers for each related part. If you want more control over constructing the MIME hierarchy itself, you can use the AddRelatedBodyPart method in conjunction with the IMessage.HTMLBody property. AddRelatedBodyPart automatically correlates the resource added as a body part to the message with the HTML that references it. This method creates the multipart/related hierarchy if required, and, depending upon your preference, associates the referenced resource in the HTML with the related body part using Content-Location or Content-ID headers.

If you want to perform all of the steps manually, you can create the multipart/related MIME hierarchy using only the IBodyPart.Fields, IBodyPart.GetDecodedContentStream, and IBodyPart.AddBodyPart methods. This approach provides the highest flexibility, but also requires the most code and the best understanding of the MHTML specification. You must populate the content stream of each body part with the appropriate resource and manually set all header fields.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


MIME Extensions to Internet Mail

Multipurpose Internet Mail Extensions (MIME) grew out of a need to encapsulate messages within messages. It now includes multipart messages that can consist of a variety of file types such as images, audio, and video.

MIME is consistent with Internet mail protocols using headers and bodies. It allows for transmission of 7-bit printable US-ASCII characters and maximum 1000-character lines in message bodies over all Internet mail transports. It has become the most widely used extension to the simple e-mail standard (see About Simple Internet (RFC 822) Messages). MIME is also used as a transport mechanism in Web pages.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


MIME Capabilities

Multipurpose Internet Mail Extensions (MIME) defines a message format that allows for:

  • Textual message bodies in character sets other than US-ASCII.
  • Non-textual message bodies.
  • Multipart message bodies.
  • Textual header information in character sets other than US-ASCII.

MIME provides a mechanism for sending a variety of file types as a part of or along with regular mail messages. It uses the headers defined by Request for Comments (RFC) 822 and extensions to those header definitions. MIME does all this while following all the standard Simple Mail Transport Protocol (SMTP) and RFC 822 mail rules. MIME messages can be constructed to transport mail over any mail transport system that is compliant with SMTP. MIME is able to transmit objects with varying degrees of complexity in a way that allows any MIME-compliant user agent (UA) to faithfully process them and hand them off to an appropriate application.

To simplify and rebuild a complex file, MIME encodes the file (see Content-Transfer-Encoding) and transports it as a message body, or as a series of messages with component parts of the file. On the receiving end, a MIME-compliant user agent (UA) decodes the message and presents it to the reader, or passes it as a file to another application. A UA that is not MIME-compliant can process a MIME-encoded e-mail message, but might not be able to decode the message.

MIME allows for multipart mail messages, ensuring that even the UA with the most limited capabilities can process the message. The multiple parts are arranged so that the parts requiring the least sophisticated UA are at the beginning of the message. Most MIME UAs include courtesy text to give users of non-MIME UAs an indication of the message content. This text is inserted ahead of any MIME parts.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Sample MIME Message

Multipurpose Internet Mail Extensions (MIME) uses headers and separators that tell a user agent (UA) how to re-create the message. The MIME message in the following example includes a text message and an attached text file. Both are body parts of the message, which does not contain encoded body parts.

From: Some One <someone@microsoft.com>
MIME-Version: 1.0
Content-Type: multipart/mixed;
        boundary="XXXXboundary text"

This is a multipart message in MIME format.

--XXXXboundary text
Content-Type: text/plain

this is the body text

--XXXXboundary text
Content-Type: text/plain;
Content-Disposition: attachment;
        filename="test.txt"

this is the attachment text

--XXXXboundary text--

The "MIME-Version:" header tells the receiving UA to treat this as a MIME message.

The "Content-Type:" header specifies "multipart/mixed". This tells the receiving UA that this message has parts separated by the string argument defined in "boundary=". A MIME-compliant UA will only display or otherwise process content following the specified "boundary=" text strings. The actual boundaries are constructed using the "boundary=" string, prepended by "--". The final body part is followed by the "boundary=" string with the "--" both prepended and appended.

In the preceding example, the courtesy message "This is a multipart message in MIME format." will not be displayed or otherwise processed by the MIME UA because it does not follow a "boundary=" string. A UA that does not support MIME will display it, and at least this part of the message will be readable no matter what features the UA supports. If the example had encoded parts, they would make no sense to the human reader using a non-MIME-compliant UA, but at least the courtesy message would give the user a hint as to why not.

There are two message body parts in the preceding example. Each body part has headers of its own, in addition to the overall message headers. Each body part begins with the boundary string. If there were no headers in the body parts, then the blank line that must follow headers in Request for Comments (RFC) 822 messages would follow the boundary string. The first body part is a plain text message, the message the sender might have typed into a UA. Its single "Content-Type:" header identifies it as "text/plain", meaning US-ASCII characters are used exclusively and any UA should be able to display this body part. Text/plain is the default content type.

The second body part in this example contains the file attachment. Because the file attachment is an ASCII text file, it is sent with no encoding and its content-type is given as text/plain. The "Content-Disposition: attachment" header has a parameter, "filename=", which specifies a suggested name for the file. This header specifies that this body part is to be treated as a file and saved on local storage under the suggested file name (instead of being displayed to the user).

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


MIME Headers

Multipurpose Internet Mail Extensions (MIME) headers appear at the beginning of a MIME message as well as within the separate body parts. Some MIME headers can be used both as message headers and in MIME body parts. Some additional headers are defined for use only in body parts.

The following headers are defined in MIME:

  • MIME-Version
  • Content-Type
  • Content-Transfer-Encoding
  • Content-ID
  • Content-Description
  • Content-Disposition

There are additional headers that are applied in specialized situations, such as Content-Base and Content-Location. All of the "Content-xxx" headers have defined sub-headers, fields, and/or parameters. Headers that begin with "Content-" are the only headers that have defined meaning in body parts. All other body part headers can be ignored and might actually be removed by message transfer agents (MTAs).

MIME-Version is a required header indicating that this message is to use the rules of MIME. "MIME-Version: 1.0" is the only currently defined MIME-Version header allowed. The MIME-Version header is a top-level header only and does not appear in body parts unless the body part is an encapsulated, fully formed message of content-type message/RFC 822, which might have its own MIME-Version header.

Content-Type headers are used to specify the media type and subtype of data in the body of a message and to fully specify the native representation of such data. This header embodies much of the power of MIME. The IETF can add new official content types. Additionally, private content-type values can be defined by anyone. Such private content types have values of "x-something" or "X-something", where "something" can take on any value.

Content-Transfer-Encoding headers can have two different meanings. If the value is "base64" or "quoted-printable", then the header indicates the encoding used for this body part. If the value is "7bit", "8bit", or "binary", then the header indicates that there is no encoding and that this value indicates only the type of content this body part contains. The default is "7bit". It should be noted that "8bit" and "binary" cannot be assured of being handled by all Internet (SMTP) MTAs, and are not actually valid in Internet mail. Provision is made for private Content-Transfer-Encoding headers. These have values that begin with "x-" or "X-". These are for specialized cases where the users have the tools to decode or otherwise process a specific "x-" encoding.

Content-ID headers are world-unique values that identify body parts, individually or as groups. They are necessary at times to distinguish body parts and allow cross-referencing between body parts.

Content-Description headers are optional and are often used to add descriptive text to non-textual body parts.

Content-Disposition headers provide information about how to present a message or a body part. When a body part is to be treated as an attached file, the Content-Disposition header will include a file name parameter.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Content-Type

The example in Sample MIME Message shows how Multipurpose Internet Mail Extensions (MIME) uses headers and multiple body parts. But the real power of MIME is in its ability to handle a wide variety of content types. Some encoding schemes are defined by MIME. An even broader range of possibilities is anticipated, and organizational elements are provided to handle the rich set of possibilities inherent in MIME. The "Content-Type:" header field is specified to organize media types. This allows the user agent (UA) to present the body part to the user in its appropriate form, to engage the services of a tool that can process the body part, or to save the body part as a file for offline processing. The content type can be either "composite" or "discrete."

The two composite top-level media types are:

  • Multipart
  • Message

The five discrete top-level media types are:

  • Text
  • Image
  • Audio
  • Video
  • Application

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Content-Type: application

The application content type allows for the transmission of application data or binary data, effectively allowing for specific handling of application data. The following application subtypes might be encountered:

application/cals-1840 [RFC1895]

application/marc [RFC2220]

application/news-message-id [RFC1036]

application/news-transmission [RFC1036]

application/octet-stream [RFC1521]

application/oda [RFC1521]

application/pgp-encrypted [RFC2015]

application/pgp-keys [RFC2015]

application/pgp-signature [RFC2015]

application/pkcs7-MIME [RFC2311]

application/pkcs7-signature [RFC2311]

application/pkcs10 [RFC2311]

application/postscript [RFC1521]

application/remote-printing [RFC1486]

application/sgml [RFC1874]

application/x400-bp [RFC1494]

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Content-Type: audio

The audio content type allows standardized audio files to be included in messages.

audio/32kadpcm [RFC1911]

audio/basic [RFC1521]

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Content-Type: image

The image content type allows standardized image files to be included in messages.

image/g3fax [RFC1494]

image/gif [RFC1521]

image/ief (Image Exchange Format) [RFC1314]

image/jpeg [RFC1521]

image/tiff (Tag Image File Format) [RFC2301]

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Content-Type: message

The message content type allows messages to contain other messages or pointers to other messages.

message/delivery-status [RFC1894] | The message/delivery-status content type is defined for use in message delivery status notification, allowing automated information transmission.
message/disposition-notification-to [RFC2298] | The message/disposition-notification-to content type adds enhanced functionality to messaging. This works within the framework of the multipart/report content type.
message/external-body [RFC1521] | The message/external-body content type allows the contents of a message to be external to the message and only referenced in the message. The only required parameter of this content type is access-type, which can have values such as "FTP" and "LOCAL-ACCESS." If values are used that have not been registered with IANA, then they begin with "x-". Message/external-body parts must include a Content-ID header field with a unique identifier to reference the external data.
message/http [RFC2068] | The message/http content type is not strictly a Multipurpose Internet Mail Extensions (MIME) content type. Provisions are made in the definition of HTTP to allow it to be used over MIME transport mechanisms, but there must be a conversion between HTTP and MIME for strict MIME adherence.
message/partial [RFC1521] | The message/partial content type allows for large messages to be broken up into smaller messages. The full message can then be put back together by the UA. Only 7bit content-transfer-encoding is allowed for this content type. Three parameters are required: id, a unique identifier used to match up the pieces; number, an integer identifying which piece of the message this is; and total, an integer indicating the total number of parts the message has. The third parameter, total, is required only on the final fragment of the message, but should be used on all parts.
message/rfc822 [RFC1521] | The message/RFC 822 content type is used to enclose a complete message within a message. It is different from other MIME body parts in that it must be a fully formed Request for Comments (RFC) 822 message, complete with headers.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Content-Type: multipart

Multipart Content-Type headers identify multipart messages. They require that a subtype and other elements be included in the header.

multipart/alternative [RFC1521] | The multipart/alternative content type is used when the same information is presented in different body parts in different forms. The body parts are ordered by increasing complexity. For example, a message that consists of a heavily formatted Microsoft® Word 97 document might also be presented in Word 6.0 format, rich text format, and a plain text format. In this case the plain text would be presented as the first alternative body part. The rich text version would follow, then the Word 6.0, then the most complex, Word 97. Placing the plain text version first is the friendliest scheme for user agents (UAs) that are not compliant with Multipurpose Internet Mail Extensions (MIME), because they will see the recognizable version first. MIME-compliant UAs should present the most complex version that they can recognize or give the user a choice of which version to view. Content-ID values should be different for each part where there are different levels of complexity between parts. The content-ID of each part should be different from the content-ID of the overall multipart/alternative. That is, one content-ID value will refer to the multipart/alternative entity, while one or more other content-ID values will refer to the parts inside it.
multipart/byteranges [RFC2068] | The multipart/byteranges content type is defined as a part of the HTTP message protocol. It includes two or more parts, each with its own Content-Type and Content-Range fields. The parts are separated using a MIME boundary parameter. This allows for binary as well as 7-bit and 8-bit files to be sent as multiple parts with the lengths of the parts being specified in the header of each part. Note that while HTTP makes provisions for using MIME for HTTP documents, HTTP is not strictly MIME-compliant.
multipart/digest [RFC1521] | The multipart/digest content type is used to send collections of plain-text messages. This is accomplished in the same way as the multipart/mixed content-type, but each body part is expected to be of content-type: message/RFC 822.
multipart/form-data [RFC1867] | The multipart/form-data content type is intended to allow information providers to express file upload requests uniformly, and to provide a MIME-compatible representation for file upload responses.
multipart/mixed [RFC1521] | The multipart/mixed content type is used when the body parts are independent and need to be bundled in a particular order. When a UA does not recognize a multipart subtype, it will treat the message as multipart/mixed.
multipart/parallel [RFC1521] | The purpose of the multipart/parallel content type is to display all of the parts simultaneously on hardware and software that can do so. For instance, an image file can be displayed while a sound file is playing.
multipart/related [RFC2112] | The multipart/related content type is used for compound documents (that is, messages in which the separate body parts are intended to work together to provide the full meaning of the message). Additionally, multipart/related can be used to provide links to content not contained within the message. Multipart/related can be used for compound documents where the object is built progressively from pieces, starting with the "root" body part as specified in the start parameter. If the start parameter is not specified, then the first body part is considered the starting point or "root" body part. Multipart/related requires a type parameter. The type parameter specifies the content type of the first or "root" part. Multipart/related processing takes precedence over content-disposition. Many MIME user agents do not recognize multipart/related and treat these messages as multipart/mixed. To allow for this, some UAs will include the technically unnecessary Content-Disposition header in multipart/related body parts. Content-Location and Content-Base headers are defined to resolve URL references to other body parts. Both headers are valid in any message or body part. They are valid for the content heading or message heading where they occur and for its content. The Content-Location and Content-Base headers apply to headers and body parts where they occur and do not have meaning in multipart headings. The Content-Base header gives a base for relative URIs occurring in other heading fields and in HTML documents that do not have any BASE element in its HTML code. Its value must be an absolute Uniform Resource Identifier (URI). The Content-Location header contains a URL that specifies the body of that body part. The URL may be relative to a URL specified in a Content-Base header. The following example shows how these headers are used:
Content-Type: Multipart/related; boundary="boundary-content_example";
type=Text/HTML; start=example@somplace.com
;Content-Base header not allowed here
;since this is a multipart MIME object
--boundary-content_example
Part 1:
Content-Type: Text/HTML; charset=US-ASCII
Content-ID: <example@somplace.com>
Content-Location: http://www.webpage/images/the.one
; This Content-Location must contain an absolute URL,
; since no base; is valid here.
--boundary-content_example
Part 2:
Content-Type: Text/HTML; charset=US-ASCII
Content-ID: <example2@somplace.com>
Content-Location: the.one ; The Content-Base below applies to
; this relative URL
Content-Base: http://www.webpage/images/
--boundary-content_example--

multipart/report [RFC1892] | The multipart/report content type was defined for returning delivery status reports, with optional included messages. It is finding wider use in machine-to-machine communication. The multipart/report is used for Message Disposition Notification.
multipart/signed, multipart/encrypted [RFC1847] | The multipart/signed and multipart/encrypted content types provide a security framework for MIME parts. These headers do not define security protocols, but exist to carry the protected documents. Each multipart/signed or multipart/encrypted body part is carried as two related parts, one with the control information describing the protocol and one with the protected document. The multipart/signed content type specifies how to support authentication and integrity services using digital signature. The control information is carried in the second of the two required body parts. The multipart/encrypted content type specifies how to support confidentiality using encryption. The control information is carried in the first of the two required body parts.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Content-Type: text

The text content type is used for message content that is primarily in human-readable text character format. The more complex text content types are defined and identified so that an appropriate tool can be used to display more complex body parts.

text/enriched [RFC1896] | The text/enriched content type is intended to be simple enough to make multifont, formatted e-mail widely readable. It uses a very limited set of formatting commands that all begin with <commandname> and end with </commandname>, affecting the formatting of the text between those two tokens.
text/html [RFC1866] | The text/html content type is an Internet Media Type as well as a Multipurpose Internet Mail Extensions (MIME) content type. Using HTML in MIME messages allows the full richness of Web pages to be available in e-mail.
text/plain [RFC1521] | The text/plain content type is the generic subtype for plain text. It is the default specified by Request for Comments (RFC) 822.
text/rfc822-headers [RFC1892] | The text/RFC 822-headers content type provides a mechanism for a Message Transfer Agent (MTA) to label and return only the RFC 822 headers of a failed message. Only the headers are returned, not the complete message. The returned headers are useful for identifying the failed message and for diagnosing delivery problems. All headers are to be returned, up to the blank line following the headers.
text/richtext [RFC1521] | The text/richtext content type has been made obsolete by text/enriched.
text/sgml [RFC1874] | The text/SGML content type should be used when the content of the Standard Generalized Markup Language (SGML) entity is intended to be read by a human and can be easily discerned without SGML display software. Each record in the SGML entity, delimited by record start (RS) and record end (RE) codes, must correspond to a line in the text/SGML body part.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Content-Type: video

The video content type allows standardized video files to be included in messages.

video/mpeg [RFC1521]

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Content-Transfer-Encoding

Many message transfer agents properly handle only short lines of US-ASCII characters. This is referred to as "7bit" or sometimes as "7bit encoded" text. Simple Mail Transport Protocol (SMTP) imposes this limit. In order to send a richer set of file types across the Internet so that all Message Transfer Agents (MTAs) can properly process them, some sort of encoding must be used. The purpose of the encoding is to use only 7-bit characters and limited line lengths to represent the content of the file. The file can be an image file, an executable file, or any general binary file.

While there are five content-transfer-encoding values defined, along with the extensible X-token, the base64 and quoted-printable are the only actual encoding schemes defined by Multipurpose Internet Mail Extensions (MIME). These two schemes offer the extremes in the tradeoff between the need for a compact and efficient scheme and the desire for a generally human-readable scheme. The base64 is a totally mapped and fairly efficient encoding scheme for binary files. The quoted-printable scheme is used for mostly 7-bit data and is readable by humans.

There are three values of content-transfer-encoding that can be used in Internet SMTP messages. The 7bit is the definitive SMTP mechanism. The base64 and quoted-printable are encoding schemes that ensure that the content will properly pass through all MTAs. The 8bit and binary content-transfer-encoding values are defined to explicitly identify content which may require processing or encoding before being packaged for Internet transfer.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Content-Transfer-Encoding: 7bit

The 7bit is the most fundamental message encoding. Actually, 7bit is not encoded; 7bit encoded files are files that use only 7-bit characters and have lines no longer than 1000 characters. CR (carriage return) and LF (line feed) characters can only occur as pairs to limit the line length to 1000 characters, including the carriage return/line feed (CR/LF) pair. NULL characters are not allowed. 7bit encoded files need no encoding or decoding. This is the default.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Content-Transfer-Encoding: 8bit

8bit encoding has the same line-length limitations as 7bit encoding. It allows 8bit characters. No encoding or decoding is required for 8bit files. Since not all Message Transfer Agents (MTAs) can handle 8bit data, the 8bit encoding is not a valid encoding mechanism for Internet mail.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Content-Transfer-Encoding: base64

Base64 encoding is the scheme used to transmit binary data. Base64 processes data as 24-bit groups, mapping this data to four encoded characters. It is sometimes referred to as 3-to-4 encoding. Each 6 bits of the 24-bit group is used as an index into a mapping table (the base64 alphabet) to obtain a character for the encoded data. The encoded data has line lengths limited to 76 characters. The characters used in base64 encoding, the base64 alphabet, include none of the special characters of importance to Simple Mail Transport Protocol (SMTP) or the hyphen used with Multipurpose Internet Mail Extensions (MIME) boundary strings.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Content-Transfer-Encoding: binary

Binary encoding is simply unencoded binary data. It has no line-length limitations. Binary encoded messages are not valid Internet messages.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Content-Transfer-Encoding: quoted-printable

Quoted-printable encoding is used where data is mostly US-ASCII text. It allows for 8-bit characters to be represented as their hexadecimal values. For instance, a new line can be forced by using the following string: "=0D=0A". Line lengths are limited to 76 characters. Using an equal sign as the last character on the line as a "soft" line break accommodates longer lines. The 76-character limit does not include the carriage return/line feed (CR/LF) sequence or the equal sign.

Any character, except the CR/LF sequence, can be represented by an equal sign followed by a two-digit hexadecimal representation. This is especially useful in getting mostly text messages to pass reliably through gateways such as EBCDIC where such characters as "{" and "}" have special meaning.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Content-Transfer-Encoding: X-token

Private or proprietary encoding schemes can be included in messages by having specialized User Agents (UAs) or applications available to both the sender and the receiver, each recognizing an agreed upon x-token and providing their own encoding mechanism. The x-token can be any character string preceded by "x-" or "X-".

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Content-Disposition

Content-Disposition headers are included to allow a message to be tagged to indicate its presentation mechanism or its archival disposition, a file name.

Some User Agents (UAs) may ignore Content-Disposition headers when they appear within multipart/related body parts.

Content-Disposition headers cannot contain comments.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Content-Disposition: attachment

Body parts designated as containing attachments require user action to be displayed and are normally split out of the message. They are typically stored as files for subsequent access. The optional parameters for this header are: file name, creation-date, modification-date, read-date, and size.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Content-Disposition: inline

Inline content is displayed to the user when the message is opened. The inline body parts are to be displayed in the order they appear in the message, subject to applicable rules for multipart content type. If a multipart body part has an inline header, the inline designation applies to the multipart as a whole, not to its subparts.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Internet Mail RFCs

The following Request for Comments (RFC) specifications address Multipurpose Internet Mail Extensions (MIME):

822, 934, 1000, 1036, 1039, 1049, 1314, 1341, 1486, 1494, 1495, 1521, 1522, 1601, 1602, 1652, 1730, 1738, 1847, 1866, 1867, 1892, 1894, 1896, 1911, 2000, 2015, 2017, 2026, 2045, 2046, 2047, 2048, 2049, 2068, 2076, 2077, 2110, 2111, 2112, 2122, 2183, 2184, 2220, 2231, 2234, 2298, 2301, 2311, 2318

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Internet Messages and SMTP

Standard for the Format of Advanced Research Projects Agency (ARPA) Internet Text Messages is the title of Request for Comments (RFC) 822, the document that has defined the format of Internet mail messages since its publication in August of 1982. This straightforward format has been very successful. In fact, it has been adopted, wholly or partially, well beyond the confines of the Internet and the Internet Simple Mail Transport Protocol (SMTP) transport, which is defined in RFC 821.

A basic understanding of RFC 822 messages and Multipurpose Internet Mail Extensions (MIME) extensions is useful for people who use CDO to create MIME formatted messages. Many properties and methods, for example, IBodyPart.ContentMediaType, require that you have some understanding of RFC 822 and MIME.

As the RFC 822 message format has seen wider use, a number of its limitations have proven increasingly restrictive. These limitations and the ways they were circumvented are described more fully in MIME Extensions to Internet Mail.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


About Simple Internet (RFC 822) Messages

This section briefly describes the format of the simple Internet message. For the original in-depth description, see Request for Comments (RFC) 822 itself http://www.rfc-editor.org/rfc/rfc822.txt.

RFC 822 messages have two major parts:

  • Message envelope: The message envelope contains all the information needed to accomplish transmission and delivery of the message. This information includes the e-mail address of the message's creator—also known as the originator. This string matches the information in the "Sender:" header, if this header is present. The envelope is created by a user agent—such as Microsoft® Outlook® and is meaningful only to the message transfer agents that move the message on the path to its destination.
  • Message contents: The contents make up the object to be delivered to the recipient. Message contents consist of lines of ASCII text. This text is arranged in the classic "memo" format, in which the message contains one or more introductory headers and a body. Persons and/or applications that want to assemble or read e-mail messages using CDO use the headers and the body.

This structure can be seen in the following illustration:

You can identify the headers and body within the contents of the sample Internet mail message in the following topic.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Simple Internet Mail Message: An Example

As you can see in the following sample of a message's contents, the format described in Request for Comments (RFC) 822 produces messages readable with little difficulty by humans.

The first few lines, from the first instance of "Received" to "Precedence," are headers. These lines define the recipients, the sender, the date, and other information involved with message transmission.

Following the headers is a blank line. This is marked by the consecutive occurrence of the four characters CR, LF, CR, and LF. The body of the message starts after this blank line. In the following example, only the final few lines make up the message body.

Received: from someone@microsoft.com
Message-Id: <v0214040cad6a13935723@>
Mime-Version: 1.0
Content-Type: text/plain; charset="us-ascii"
Date: Thursday, 4 Jun 1998 09:43:14 -0800
To: project-discussion@microsoft.com
From: Nina Marton <nina@microsoft.com>
Subject: Happy Birthday
Precedence: bulk

Happy Birthday!
See you this evening,
Nina

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


About SMTP

As important as the format of electronic messages is the transfer protocol for which that format was created. This is Simple Mail Transport Protocol (SMTP), the Internet protocol for electronic mail. It is defined in Request for Comments (RFC) 821, the companion document to RFC 822.

SMTP is just one part of the Transmission Control Protocol/Internet Protocol (TCP/IP) protocol suite. SMTP standardizes communication between message transger agents (MTAs) by defining how messages move from one computer's MTA to another computer's MTA. SMTP does not, however, specify the message's path to the destination computer. This path can be direct, or it can lead through intermediate computers in a process known as store and forward.

Because the SMTP protocol is concerned only with moving messages, it limits the formatting attributes of messages. SMTP transfers only ASCII text, with no fonts, colors, graphics, or attachments. Multipurpose Internet Mail Extensions (MIME) extensions provide workarounds for these limitations.

In the early days of the Internet, SMTP gained widespread use through its close connection to UNIX-based systems. At first it was used only with UNIX tools, such as the e-mail program sendmail. Today SMTP is the still the standard e-mail protocol for the Internet, but Internet hosts use a wide variety of operating systems, and people can read and send their mail with any user agent (UA) that can communicate with an MTA.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Summary of RFC 822

Request for Comments (RFC) 822 was revised by David H. Crocker, of the Department of Electrical Engineering at the University of Delaware, and published on August 13, 1982. It made RFC 733 (NIC #41952) obsolete.

The following topics summarize the major sections of RFC 822.

RFC 822: Introduction

RFC 822: Notational Conventions

RFC 822: Lexical Analysis of Messages

RFC 822: Message Specification

RFC 822: Date and Time Specification

RFC 822: Address Specification

RFC 822: Appendixes

Note A few parts of the following summary are taken verbatim from RFC 822, but most have been shortened and paraphrased. For complete details, see the original document.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


RFC 822: Introduction

The purpose of Request for Comments (RFC) 822 is to revise the standards that had previously been codified, culminating in RFC 733. The document's scope is the syntax of e-mail text messages. Messages contain two major parts, envelope and contents (see About Simple Internet (RFC 822) Messages), though the envelope is specifically not described in the document.

In a forward-looking way, RFC 822 states that, although its specifications are intended for use on the Advanced Research Projects Agency (ARPA) Internet, "an attempt has been made to free it of any dependence on that environment, so that it can be applied to other network text message systems."

Also, RFC 822 defines only what information is passed between Internet hosts, not how messaging systems are used to store, create, or read messages or the information they contain.

About Message Contents and Framework

Messages consist of "lines of text," with no special provisions made for encoding drawings, facsimile, speech, or structured text. Little consideration is given to questions of data compression or to transmission and storage efficiency.

The RFC 822 message will use a general "memo" framework in which initial information is presented in a rigid, defined format (the headers section) followed by the main part of the message whose format is unspecified.

The described framework has limitations, specifically that its constraints on document tone and appearance make messages of this format "primarily useful for most intra-organization communications and well-structured, inter-organization communication, as well as for some types of inter-process communication, such as simple file transfer and remote job entry."

It is speculated that "a more robust framework might allow for multi-font, multi-color, multidimensional encoding of information," whereas "a less robust one, as is present in most single-machine message systems, would more severely constrain the ability to add fields and the decision to include specific fields."

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


RFC 822: Notational Conventions

The notation used in Request for Comments (RFC) 822 is based on the Backus-Naur Form (BNF) convention but was recoded by Ken L. Harrenstien into an "augmented BNF that makes the representation smaller and easier to understand."

This section primarily describes how rules (which describe the syntax of the message format) are used in the rest of the document. It includes the following notes:

  • Quotation marks enclose literal text, which may be upper and/or lowercase.
  • Certain basic rules are in uppercase, such as SPACE, TAB, CRLF, DIGIT, ALPHA, and so on.
  • Elements separated by a forward slash (/) are alternatives.
  • Elements enclosed in parentheses are treated as a single element.
  • Square brackets enclose optional elements.
  • The asterisk character (*) preceding an element indicates repetition of that element an unspecified number of times.
  • Repetition a specified number of times is indicated by use of a digit: <n>(element) is equivalent to <n>*<n>(element)—that is, exactly <n> occurrences of (element). Thus 2DIGIT is a 2-digit number, and 3ALPHA is a string of three alphabetic characters.
  • Lists are made using the # character. The construct # is defined, similar to *, as follows: <l>#<m>element.
  • A semicolon, set off some distance to the right of rule text, starts a comment that continues to the end of line.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


RFC 822: Lexical Analysis of Messages

A message consists of header fields and, optionally, a body. The body is simply a sequence of lines containing ASCII characters. It is separated from the headers by a null line, that is, a line with nothing preceding the carriage return/line feed (CR/LF).

About Header Fields

Each header field is a single line of ASCII characters, and it contains a field name and a field body. A header field can be viewed as being composed of a field name, followed by a colon (:), followed by a field body, and terminated by a CR/LF.

Wrapping Field Bodies

The field-body portion of a header can be wrapped into a multiple-line representation. The general rule is that wherever there is linear-white-space (not simply LWSP-characters), a CR/LF immediately followed by at least one LWSP-character can instead be inserted.

This word-wrap capability is referred to in Request for Comments (RFC) 822 as "folding," and the process of moving from the multiple-line representation of a header field to its single-line representation is called "unfolding." Unfolding is accomplished by regarding a CR/LF immediately followed by an LWSP-character as equivalent to the LWSP-character alone.

Structure of Header Fields

The name of a header field must be composed of printable ASCII characters (characters with ASCII values between decimal 33 and 126, except colons). The header field body can be composed of any ASCII characters except CR or LF. (While CR and/or LF can be present in the actual text, they are removed when the field is unfolded.)

Certain header field bodies such as those for dates and addresses have internal structure. Others, such as "Subject" and "Comments", are regarded simply as strings of text, and are defined as <text>.

The Structure of Header Field Bodies

In RFC 822, this section describes the structure of fields used for headers. It is assumed that "lexical analyzer" code exists to interpret the bodies of header fields, and that those header fields consist of the following lexical symbols:

  • Individual special characters
  • Quoted-strings
  • Domain-literals
  • Comments
  • Atoms

The usage rules for the elements and structure of header fields are supported in this section by an example.

Header Field Definitions

This section lists the syntax rules for header field names and header field bodies, for the purpose of detecting fields within messages.

Lexical Tokens

The rules in this section define a "lexical analyzer," which feeds tokens to higher-level parsers. For example:

CHAR = <any ASCII character>
DIGIT       =  <any ASCII decimal digit>
LWSP-char   =  SPACE / HTAB
linear-white-space =  1*([CRLF] LWSP-char)
atom = 1*<any CHAR except specials, SPACE and CTLs>
comment = "(" *(ctext / quoted-pair / comment) ")"
word = atom / quoted-string

The Clarifications section gives more detail regarding quoting, white space, comments, and case-sensitivity.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


RFC 822: Message Specification

This section explains the broader requirements of (and recommendations for) constructing a message. For example:

  • Header fields are not required to occur in any particular order, except that the message body must occur after the headers.
  • It is recommended that, if present, headers be sent in the order "Return-Path", "Received", "Date", "From", "Subject", "Sender", "To", "cc", and so on.
  • message = fields *( CRLF *text )
  • fields = dates source 1*destination *optional-field

This section also describes the use of fields for forwarding messages, providing an audit trail to facilitate message handling (and to identify a route to the message's sender), and identifying the various hosts that sent and received the message en route. Header fields can also be used to provide information about the message's origination, in particular:

  • From: The identity of the person(s) who initiated sending the message.
  • Sender: The authenticated identity of the Agent (person, system or process) that sends the message.
  • Reply-to: Mailboxes to which responses are to be sent.

Receiver: fields are also described. These include:

  • To: The identity of the primary recipients of the message.
  • Cc: The identity of the secondary (informational) recipients of the message.
  • Bcc: The identity of additional recipients of the message. The contents of this field are not included in copies of the message sent to the primary and secondary recipients.

Reference Fields

This section describes the fields Message-ID, In-Reply-To, References, and Keywords.

Other Fields

The Subject and Comments fields are briefly described, as are the fields used for encryption, extensions to standard fields, and user-defined fields.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


RFC 822: Date and Time Specification

The syntax and semantics for the dates and times used in Request for Comments (RFC) 822 messages is defined in this section. For example, the days of the week and months of the year are enumerated, and the time is defined as:

time = hour zone ; ANSI and Military

hour = 2DIGIT ":" 2DIGIT [":" 2DIGIT] ; 00:00:00 - 23:59:59

Time zones are also specified, for example:

zone = "UT" / "GMT"
         /  "EST" / "EDT"

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


RFC 822: Address Specification

The syntax for addresses is given as follows:

address = mailbox ; one addressee / group ; named list
group = phrase ":" [#mailbox] ";"
mailbox = addr-spec ; simple address / phrase route-addr ; name & addr-spec
route-addr = "<" [route] addr-spec ">"
route = 1#("@" domain) ":" ; path-relative
addr-spec = local-part "@" domain ; global address
local-part = word *("." word) ; uninterpreted ; case-preserved
domain = sub-domain *("." sub-domain)
sub-domain = domain-ref / domain-literal
domain-ref = atom ; symbolic reference

For an example of addresses used in a Request for Comments (RFC) 822 message, see Simple Internet Mail Message: An Example.

Address Semantics

A mailbox is defined as a conceptual entity that receives mail, and does not necessarily store files; a mailbox could, for example, pass mail directly to a printer rather than storing it on disk.

A mailbox specification is defined as consisting of a person, system, or process name reference, a domain-dependent string, and a name-domain reference. The name reference is optional.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


RFC 822: Appendixes

This section of Request for Comments (RFC) 822 provides a number of examples of addresses, written to illustrate both typical and borderline cases. Examples of message headers are given that show the use of both mandatory and optional headers.

An appendix is provided that describes the differences between the specifications of RFC 733 and those of RFC 822.

Finally, the syntax rules for the basic Internet message are listed alphabetically in a table.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


SMTP/NNTP Transport Event Sinks with CDO

Implementing and managing Simple Mail Transport Protocol (SMTP)/ NNTP service transport event sinks using CDO is covered in the CDO for Microsoft® Windows® 2000 documentation.

Transport event sinks implemented with CDO for Windows 2000 will continue to function without alteration after the installation of Microsoft® Exchange 2000 Server. No recompilation or re-implementation of the sink is required. The CDO for Exchange 2000 COM component has been designed to install cleanly over the CDO for Windows 2000 COM component, and all applications, including transport event sinks, will continue to function after the installation.

If you need to update or revise the code for applications written using CDO for Windows 2000, it is recommended that you update any references to the CDOSYS component, and replace them with references to the CDO for Exchange 2000 Server (CDOEX) component.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Creating Calendaring Applications

Microsoft® Exchange 2000 Server includes rich calendaring features that you can use to build calendaring applications. CDO provides the logic necessary to create applications that incorporate appointments, meetings, messages, and other calendaring items.

The topics in this section describe how to use CDO to develop custom calendaring solutions.

Introduction

Before You Start

Concepts and Architecture

Programming Tasks

Example Code

Related Topics

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Introduction

Calendaring is the process of creating and maintaining appointments and meetings. Appointments and meetings are stored in calendars, which are folders in the Web Storage System. An appointment represents an activity that takes place on a particular date and at a specific time. A meeting is an appointment that involves more than one individual.

You can use calendaring with Microsoft® Exchange 2000 Server to:

  • Create single or recurring appointments.
  • Send requests to others to invite them to a meeting.
  • Check when others are free or busy.
  • Schedule the use of conference rooms and other resources.

Exchange 2000 Server provides a calendar for each mailbox. In addition, appointments and meetings can be placed in public folders for group calendars.

Appointments and meetings typically have a start time and an end time. Recurring appointments and meetings have multiple instances that follow a pattern. For example, you can schedule meetings that always occur at 10:00 A.M. on the first Monday of each month.

Meeting requests are sent out to invite attendees to participate in a meeting. The person sending the meeting request is called the organizer. Meeting requests are a special type of message. An attendee can respond to a meeting request by accepting, tentatively accepting, or declining. Meeting responses are also special types of messages. The organizer's copy of the meeting maintains a list of attendees and their responses.

If you send a meeting request, and later you want to make changes to the meeting, you can send an update to the attendees. As the meeting organizer, you can cancel the meeting and send a message to inform the attendees of the cancellation. Attendees cannot cancel a meeting; however, they can decline a meeting that they have already accepted.

Instead of inviting attendees to a meeting, you can publish an appointment. For example, you can send employees the list of company holidays. A published appointment has no attendees.

Finally, appointment and meeting requests can have attachments. When you send a meeting request, the attachment is sent as part of the message. An attachment can be almost anything, for example, a map showing a meeting location.

This topic covers the following information:

Calendars in Exchange 2000 Server

Calendars on the Internet

Time Zones

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Calendars in Exchange 2000 Server

In Microsoft® Exchange 2000 Server, each mailbox usually has an associated calendar folder. However, when you first create a mailbox, it does not have an associated calendar folder. The calendar folder is created in one of the following ways:

  • Microsoft® Outlook® creates a calendar folder the first time it accesses a mailbox.
  • Exchange 2000 Server creates a calendar folder the first time it delivers a message to a mailbox.

You can view your calendar using Outlook, Outlook Web Access, applications that use CDO, or any combination of the three. Exchange 2000 Server can also store appointments in public folders; typically this is done for team or project schedules.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Calendars on the Internet

New Internet standards enable you to send meeting requests to users who have various calendaring systems. The iCalendar specification (Request for Comments (RFC) 2445) defines the format of calendar information sent between calendar user agents. Calendar user agents (CUAs) are client programs such as Microsoft® Outlook®. You can use CDO to send calendar information to any CUAs that comply with the iCalendar specification.

CDO also creates a plain-text representation of calendar messages. When you send a meeting request or response to users who do not have an iCalendar-compliant e-mail client, they see the plain-text version of the meeting, including the start and end times, location, subject, and meeting description.

Microsoft® Exchange 2000 Server supports the iCalendar specification as an interchange format. Exchange 2000 Server automatically converts calendar information to the correct format for client programs including CDO, Outlook, and Schedule+.

iCalendar information is transported across the Internet formatted as a Multipurpose Internet Mail Extensions (MIME). The MIME body part containing iCalendar information has a content type of text/calendar. The following example shows a typical iCalendar meeting request:

X-Receiver: someone@microsoft.com
X-Receiver: another@microsoft.com
X-Sender: user12@exchange.microsoft.com
thread-index: Ab76K9YbzaPyz4RUTJWwZL3wQ+HxyA==
Content-Class: urn:content-classes:calendarmessage
From: <user12@exchange.microsoft.com>
Sender: <user12@exchange.microsoft.com>
To: <someone@microsoft.com>
Cc: <another@microsoft.com>
Subject: Documentation Review Meeting
Date: Wed, 8 Sep 1999 11:56:19 -0700
Message-ID: <000201befa2b$d62c2e70$79b41eac@exchange.microsoft.com>
MIME-Version: 1.0
Content-Type: multipart/alternative;
   boundary="----=_NextPart_000_0003_01BEF9F1.29D23870"
Content-Transfer-Encoding: 7bit
X-Mailer: Microsoft CDO for Exchange Server
X-MimeOLE: Produced By Microsoft MimeOLE V5.00.2919.5500

This is a multi-part message in MIME format.

------=_NextPart_000_0003_01BEF9F1.29D23870
Content-Type: text/plain;
   charset="us-ascii"
Content-Transfer-Encoding: 7bit

Type       : Single Meeting
Organizer  : MAILTO:user12@exchange.microsoft.com
Start Time : 09/09/1999 10:00
End Time   : 09/09/1999 11:30
Time Zone  : Local time
Location   : Executive Conference Room

*~*~*~*~*~*~*~*~*~*

------=_NextPart_000_0003_01BEF9F1.29D23870
Content-Class: urn:content-classes:calendarmessage
Content-Type: text/calendar;
   method=REQUEST;
   charset="utf-8"
Content-Transfer-Encoding: 7bit

BEGIN:VCALENDAR
METHOD:REQUEST
PRODID:Microsoft CDO for Microsoft Exchange
VERSION:2.0
BEGIN:VEVENT
DTSTAMP:19990908T185620Z
DTSTART:19990909T100000
SUMMARY:Documentation Review Meeting
UID:{A6DEF157-DFCE-40F4-AC77-217563191E7B}
ATTENDEE;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-ACTION;RSVP=TRUE:MAILTO:someone@microsoft.com
ATTENDEE;ROLE=OPT-PARTICIPANT;PARTSTAT=NEEDS-ACTION;RSVP=TRUE:MAILTO:another@microsoft.com
ORGANIZER;ROLE=REQ-PARTICIPANT;PARTSTAT=ACCEPTED;RSVP=TRUE:MAILTO:user12@exchange.microsoft.com
LOCATION:Executive Conference Room
DTEND:19990909T113000
SEQUENCE:0
PRIORITY:5
CLASS:Personal
CREATED:19990908T185620Z
LAST-MODIFIED:19990908T185620Z
STATUS:CONFIRMED
TRANSP:OPAQUE
X-MICROSOFT-CDO-BUSYSTATUS:BUSY
X-MICROSOFT-CDO-INSTTYPE:0
END:VEVENT
END:VCALENDAR

------=_NextPart_000_0003_01BEF9F1.29D23870--

For more information about the iCalendar format, see RFC 2445.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Time Zones

Appointments are stored in the Web Storage System and are based on UTC. When you view an appointment, you need to convert the appointment to local time. Clients such as Microsoft® Outlook® automatically convert appointments to the local time of the client computer.

CDO automatically converts date and time values in the properties of CDO to local time. CDO does this based on the time zone information in the corresponding CDO Configuration object. When you save an appointment or create a calendar message, CDO converts the local time specified in the StartTime and EndTime properties of the Appointment object to UTC, based on the time zone information in the Configuration object. When CDO expands recurring appointments into individual instances, it uses the time zone information from the Appointment object.

Date and time values in the Fields collection and in the stream of CDO are converted to local time. This is done by using the time zone information from the Configuration object. By default, the CDO Appointment and Configuration objects use the system time zone value from the computer that is running CDO.

For example, you are in Brussels ( UTC + 1:00 hour) and you want to schedule a telephone conference with colleagues in Bangkok ( UTC + 7:00 hours). You create a meeting for 9:00 A.M. local time and send a meeting request. The appointment is stored in Microsoft® Exchange 2000 Server as 08:00:00 UTC. When your colleagues in Bangkok view the appointment, their calendar client programs convert UTC to local time and display the start time as 3:00 P.M.

You can also create floating appointments. Floating appointments are appointments that are not adjusted for time zones. For example, you may want to have an appointment on your calendar for lunch every day from 12:00 noon to 1:00 P.M., regardless of the time zone. You would not want lunch to convert from noon to 6:00 P.M. when you travel from Brussels to Bangkok.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Specifying the Time Zone

CDO offers two ways to specify the local time zone: the timezoneid field and the timezone field. The urn:schemas:calendar:timezoneid field uses the values from the CdoTimeZoneId enumeration. These values correspond to the Microsoft® Win32® time zone values that are used by the operating system. This field is easy to work with and should be sufficient for most applications.

The urn:schemas:calendar:timezone field provides greater flexibility, but is more complicated to use. You can use this field to specify a time zone that is not included in the CdoTimeZoneId enumeration.

The urn:schemas:calendar:timezoneid field is a string that contains a VTIMEZONE block, as defined by the iCalendar standard. If this field is specified, the urn:schemas:calendar:timezoneid field is ignored.

Both the Configuration object and the Appointment object have the urn:schemas:calendar:timezoneid and urn:schemas:calendar:timezone fields. CDO does not set the time zone of the Appointment object from the Configuration time zone.

The following example shows how to create a custom time zone by using the urn:schemas:calendar:timezone field. This example creates a time zone that is the same as the United States and Canada, Pacific time.

Visual Basic

Dim Config As New CDO.Configuration
Dim timezone As String

timezone = timezone & "BEGIN:VTIMEZONE" & vbCrLf
timezone = timezone & "TZID:Same as Pacific" & vbCrLf
timezone = timezone & "BEGIN:STANDARD" & vbCrLf
timezone = timezone & "DTSTART:16010101T020000" & vbCrLf
timezone = timezone & "TZOFFSETFROM:-0700" & vbCrLf
timezone = timezone & "TZOFFSETTO:-0800" & vbCrLf
timezone = timezone & "RRULE:FREQ=YEARLY;WKST=MO;INTERVAL=1;BYMONTH=10;BYDAY=-1SU" & vbCrLf
timezone = timezone & "END:STANDARD" & vbCrLf
timezone = timezone & "BEGIN:DAYLIGHT" & vbCrLf
timezone = timezone & "DTSTART:16010101T020000" & vbCrLf
timezone = timezone & "TZOFFSETFROM:-0800" & vbCrLf
timezone = timezone & "TZOFFSETTO:-0700" & vbCrLf
timezone = timezone & "RRULE:FREQ=YEARLY;WKST=MO;INTERVAL=1;BYMONTH=4;BYDAY=1SU" & vbCrLf
timezone = timezone & "END:DAYLIGHT" & vbCrLf
timezone = timezone & "END:VTIMEZONE" & vbCrLf

Config.Fields(cdoTimeZoneURN) = timezone
Config.Fields.Update

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Making Time Zones Work with Outlook

Microsoft® Outlook® converts appointments from UTC to the local time of the computer running Outlook when it displays them from the Web Storage System. Conversely, Outlook converts appointments from local time to UTC when it saves them in the Web Storage System. As long as appointments are saved with the correct local time zone, they are displayed correctly by Outlook.

Outlook does not support floating appointments. Outlook interprets floating appointments as UTC. For example, a floating appointment with a start time of 1:00 P.M. is displayed by Outlook as 6:00 A.M in Bangkok (UTC + 7:00 hours).

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Using Recurring Appointments with Time Zones

When a recurring appointment spans standard time and daylight savings time, CDO automatically adjusts the individual appointment instances. For example, you have scheduled meetings to occur each Monday at 2:00 P.M. for an entire year. When you view any instance of the meeting during the year, the adjusted time is 2:00 P.M. The UTC value in the Web Storage System varies plus or minus the daylight savings offset, so that when the local time conversion is made, the resulting value is still 2:00 P.M.

CDO uses the time zone information from the Appointment object when expanding recurring appointments. Start and end times are automatically adjusted for standard time and daylight savings time.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Time Zone to CdoTimeZoneId Map

The following table lists the mapping of time zones presented by the Microsoft® Windows® operating system and the corresponding CdoTimeZoneId enumerated values.

Time Zone | CdoTimeZoneId Enum | Value
(UTC) Universal Coordinated Time | cdoUTC | 0
(GMT) Casablanca, Monrovia | cdoMonrovia | 31
(GMT) Greenwich Mean Time: Dublin, Edinburgh, Lisbon, London | cdoLisbon | 2
(GMT) Greenwich Mean Time; Dublin, Edinburgh, London | cdoGMT | 1
(GMT+01:00) Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna | cdoBerlin | 4
(GMT+01:00) Belgrade, Bratislava, Budapest, Ljubljana, Prague | cdoPrague | 6
(GMT+01:00) Brussels, Copenhagen, Madrid, Paris | cdoParis | 3
(GMT+01:00) Paris, Madrid, Brussels, Copenhagen | cdoParis | 3
(GMT+01:00) Prague, Central Europe | cdoPrague | 6
(GMT+01:00) Sarajevo, Skopje, Sofija, Vilnius, Warsaw, Zagreb | cdoSarajevo | 2
(GMT+01:00) West Central Africa | cdoWestCentralAfrica | 69
(GMT+02:00) Athens, Istanbul, Minsk | cdoAthens | 7
(GMT+02:00) Bucharest | cdoEasternEurope | 5
(GMT+02:00) Cairo | cdoCairo | 49
(GMT+02:00) Harare, Pretoria | cdoHarare | 50
(GMT+02:00) Helsinki, Riga, Tallinn | cdoHelsinki | 59
(GMT+02:00) Israel, Jerusalem Standard Time | cdoIsrael | 27
(GMT+03:00) Baghdad | cdoBaghdad | 26
(GMT+03:00) Arab, Kuwait, Riyadh | cdoArab | 74
(GMT+03:00) Moscow, St. Petersburg, Volgograd | cdoMoscow | 51
(GMT+03:00) East Africa, Nairobi | cdoEastAfrica | 56
(GMT+03:30) Tehran | cdoTehran | 25
(GMT+04:00) Abu Dhabi, Muscat | cdoAbuDhabi | 24
(GMT+04:00) Baku, Tbilisi, Yerevan | cdoCaucasus | 54
(GMT+04:30) Kabul | cdoKabul | 48
(GMT+05:00) Ekaterinburg | cdoEkaterinburg | 58
(GMT+05:00) Islamabad, Karachi, Sverdlovsk, Tashkent | cdoIslamabad | 47
(GMT+05:30) Calcutta, Chennai, Mumbai, New Delhi, India Standard Time | cdoBombay | 23
(GMT+05:45) Kathmandu, Nepal | cdoNepal | 62
(GMT+06:00) Almaty, Novosibirsk, North Central Asia | cdoAlmaty | 46
(GMT+06:00) Astana, Dhaka | cdoDhaka | 71
(GMT+06:00) Sri Jayawardenepura, Sri Lanka | cdoSriLanka | 66
(GMT+06:30) Rangoon | cdoRangoon | 61
(GMT+07:00) Bangkok, Hanoi, Jakarta | cdoBangkok | 22
(GMT+07:00) Krasnoyarsk | cdoKrasnoyarsk | 64
(GMT+08:00) Beijing, Chongqing, Hong Kong SAR, Urumqi | cdoBeijing | 45
(GMT+08:00) Irkutsk, Ulaan Bataar | cdoIrkutsk | 63
(GMT+08:00) Kuala Lumpur, Singapore | cdoSingapore | 21
(GMT+08:00) Perth, Western Australia | cdoPerth | 73
(GMT+08:00) Taipei | cdoTaipei | 75
(GMT+09:00) Osaka, Sapporo, Tokyo | cdoTokyo | 20
(GMT+09:00) Seoul, Korea Standard time | cdoSeoul | 72)
(GMT+09:00) Yakutsk | cdoYakutsk | 70
(GMT+09:30) Adelaide, Central Australia | cdoAdelaide | 19
(GMT+09:30) Darwin | cdoDarwin | 44
(GMT+10:00) Brisbane, East Australia | cdoBrisbane | 18
(GMT+10:00) Canberra, Melbourne, Sydney, Hobart (year 2000 only) | cdoSydney | 76
(GMT+10:00) Guam, Port Moresby | cdoGuam | 43
(GMT+10:00) Hobart, Tasmania | cdoHobart | 42
(GMT+10:00) Vladivostok | cdoVladivostock | 68
(GMT+11:00) Magadan, Solomon Is., New Caledonia | cdoMagadan | 41
(GMT+12:00) Auckland, Wellington | cdoWellington | 17
(GMT+12:00) Fiji Islands, Kamchatka, Marshall Is. | cdoFiji | 40
(GMT+13:00) Nuku'alofa, Tonga | cdoTonga | 67
(GMT-01:00) Azores | cdoAzores | 29
(GMT-01:00) Cape Verde Is. | cdoCapeVerde | 53
(GMT-02:00) Mid-Atlantic | cdoMidAtlantic | 30
(GMT-03:00) Brasilia | cdoBrasilia | 8
(GMT-03:00) Buenos Aires, Georgetown | cdoBuenosAires | 32
(GMT-03:00) Greenland | cdoGreenland | 60
(GMT-03:30) Newfoundland | cdoNewfoundland | 28
(GMT-04:00) Atlantic Time (Canada) | cdoAtlanticCanada | 9
(GMT-04:00) Caracas, La Paz | cdoCaracas | 33
(GMT-04:00) Santiago | cdoSantiago | 65
(GMT-05:00) Bogota, Lima, Quito | cdoBogota | 35
(GMT-05:00) Eastern Time (US & Canada) | cdoEastern | 10
(GMT-05:00) Indiana (East) | cdoIndiana | 34
(GMT-06:00) Central America | cdoCentralAmerica | 55
(GMT-06:00) Central Time (US & Canada) | cdoCentral | 11
(GMT-06:00) Mexico City, Tegucigalpa | cdoMexicoCity | 37
(GMT-06:00) Saskatchewan | cdoSaskatchewan | 36
(GMT-07:00) Arizona | cdoArizona | 38
(GMT-07:00) Mountain Time (US & Canada) | cdoMountain | 12
(GMT-08:00) Pacific Time (US & Canada); Tijuana | cdoPacific | 13
(GMT-09:00) Alaska | cdoAlaska | 14
(GMT-10:00) Hawaii | cdoHawaii | 15
(GMT-11:00) Midway Island, Samoa | cdoMidwayIsland | 16
(GMT-12:00) Eniwetok, Kwajalein, Dateline Time | cdoEniwetok | 39

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Concepts and Architecture

The following topic describes the concepts and architecture for calendaring.

The Calendar Object Model

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


The Calendar Object Model

CDO objects provide the necessary logic to work with appointments, meetings, messages, and other calendaring items. These objects make it easier for you to write calendaring applications. For an overview diagram, see CDO for Exchange 2000 Server Objects.

In CDO, the Appointment object represents appointments and meetings. Meetings have attendees, each represented by an Attendee object in the Attendees collection.

Recurring appointments and meetings are those that occur more than once and follow a pattern. A pattern is defined by using one or more RecurrencePattern objects in the Appointment object's RecurrencePatterns collection. The Exception objects in the Exceptions collection define modifications to the pattern.

You invite attendees to a meeting and attendees respond to the invitation by using messages represented by CalendarMessage objects. These messages are also used to update or cancel an existing appointment. The CalendarMessage object exposes the IMessage interface; therefore, a calendar message has all of the capabilities of any other CDO message.

The CalendarMessage object encapsulates information about one or more appointments in CalendarPart objects in the CalendarParts collection. When you process calendar messages, you extract the Appointment objects from the CalendarPart objects.

Appointment objects can have attachments. Each attachment is a BodyPart object in the appointment's Attachments collection.

Microsoft® Exchange 2000 Server stores the free/busy status of each calendar user in a special public folder. You can use the Addressee object to verify user names in the directory and to get a user's free/busy status.

The Configuration object stores information, such as the location of the user's calendar folder and the identity of the user. In general, you need to associate a Configuration object with each Appointment and CalendarMessage object.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Programming Tasks

The topics in this section describe how to develop calendaring applications.

Creating Appointments and Meeting Requests

Processing a Calendar Message

Updating Appointments and Meetings

Inviting Additional Attendees

Configuring the Appointment Object

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Creating Appointments and Meeting Requests

You can add an appointment to your calendar and request that others join you by sending them meeting requests. You add an appointment by creating a CDO Appointment object, setting information about the appointment by using the object, and then saving the item to a folder. You create a meeting request from the Appointment object by using the IAppointment.CreateRequest Method. CDO creates a special message within a CalendarMessage object that you then send to attendees to invite them to the appointment.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Adding an Appointment to the Calendar

You can add appointments to a user's personal calendar folder and to a public folder.

To add an appointment to a folder

  1. Create an Appointment object.
  2. Set the properties of the appointment. A StartTime is required.
  3. Save the appointment to the designated folder by using the Appointment object's IDataSource Interface.

The following example shows how to create an appointment and then save it to a specified folder:

Visual Basic

' Reference to Microsoft ActiveX Data Objects 2.5 Library
' Reference to Microsoft CDO for Exchange 2000 Library
Function CreateAppointment(StartTime As Date, _
                            EndTime As Date, _
                            Subject As String, _
                            Location As String, _
                            TextBody As String, _
                            iMbx As IMailbox) As Appointment

    Dim iAppt       As New Appointment
    Dim Conn        As New ADODB.Connection
    Conn.Provider = "ExOLEDB.DataSource"

    'Set the appointment properties
    With iAppt
        .StartTime = StartTime
        .EndTime = EndTime
        .Subject = Subject
        .Location = Location
        .TextBody = TextBody
        'Save the appointment
        Conn.Open iMbx.BaseFolder
        .DataSource.SaveToContainer iMbx.Calendar, Conn
    End With

    Set CreateAppointment = iAppt
End Function

C++

/*
 Assume that the following paths are in your
 INCLUDE path.
 %CommonProgramFiles%\system\ado
 %CommonProgramFiles%\microsoft shared\cdo
*/

#import <msado15.dll> no_namespace
#import <cdoex.dll> no_namespace
#include <iostream.h>

IAppointmentPtr CreateAppointment(DATE startTime, DATE endTime, bstr_t subject, bstr_t location, bstr_t textbody, const IMailboxPtr& iMbx) {

   IAppointmentPtr   iAppt(__uuidof(Appointment));
   _ConnectionPtr   Conn(__uuidof(Connection));
   IDataSourcePtr   iDsrc;

   Conn->Provider = "ExOLEDB.DataSource";

   try {
      //Set the appointment properties
      iAppt->StartTime = startTime;
      iAppt->EndTime   = endTime;
      iAppt->Subject   = subject;
      iAppt->Location  = location;
      iAppt->TextBody  = textbody;
      //Save the appointment
      iDsrc = iAppt;

      Conn->Open(iMbx->BaseFolder, bstr_t() , bstr_t(), -1);
      cout << "save to container here" << endl;
      iDsrc->SaveToContainer(iMbx->Calendar, Conn, adModeReadWrite, adCreateNonCollection, adOpenSource, bstr_t(), bstr_t() );

   }
   catch(_com_error e) {
      cout << "Error setting props on appointment??" << endl;
      throw e;
   }
   return iAppt;
}

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Sending a Meeting Request

A meeting request is a message sent by the meeting organizer to invite other users to a meeting. A meeting request contains a description of the meeting, including the start time, end time, and location. CDO creates a meeting request from an Appointment object by using the IAppointment.CreateRequest method.

To send a meeting request

  1. Create or open an Appointment object.
  2. Add attendees to the meeting by adding Attendee objects to the Appointment's Attendees collection.
  3. Save the Appointment to the organizer's calendar (optional).
  4. Create a CalendarMessage object using the IAppointment.CreateRequest method.
  5. Send the message requesting that the users attend the meeting.

The following example shows how to add attendees to an appointment and send a meeting request to the specified users:

Visual Basic

' Reference to Microsoft ActiveX Data Objects 2.5 Library
' Reference to Microsoft CDO for Exchange 2000 Library
Sub SendMeetingRequest(iAppt As CDO.Appointment, _
                        iMbx As IMailbox, _
                        strAttnMandatory() As String, _
                        strAttnOptional() As String)

    Dim iCalMsg     As CalendarMessage
    Dim Config      As New Configuration
    Dim iAttendee   As New Attendee
    Dim iPers       As CDO.Person

    'Set the configuration fields
    Set iPers = iMbx
    Config(cdoSendEmailAddress) = iPers.Email
    Config(cdoMailboxURL) = iMbx.BaseFolder
    Config.Fields.Update

    With iAppt
        .Configuration = Config

        'Add attendees
        Dim I As Long
        For I = LBound(strAttnMandatory) To UBound(strAttnMandatory)
            Debug.Print "Mandatory Attendee E-Mail:" & strAttnMandatory(I)
            Set iAttendee = .Attendees.Add
            iAttendee.Address = CStr(strAttnMandatory(I))
            iAttendee.Role = cdoRequiredParticipant
        Next I

        For I = LBound(strAttnOptional) To UBound(strAttnOptional)
            Debug.Print "Optional Attendee E-Mail:" & strAttnOptional(I)
            Set iAttendee = .Attendees.Add
            iAttendee.Address = CStr(strAttnOptional(I))
            iAttendee.Role = cdoOptionalParticipant
        Next I

        'Create the calendar message and send it
        Set iCalMsg = .CreateRequest

        'Save these changes to the appointment
        .DataSource.Save

        iCalMsg.Message.Send
    End With

End Sub

C++

/*
 Assume that the following paths are in your
 INCLUDE path.
 %CommonProgramFiles%\system\ado
 %CommonProgramFiles%\microsoft shared\cdo
*/

#import <msado15.dll> no_namespace
#import <cdoex.dll> no_namespace
#include <iostream.h>
#include <vector>
using namespace std;

void sendMeetingRequest(
                  IAppointmentPtr& iAppt,
                  IMailboxPtr& iMbx,
                  vector<bstr_t>& AttnMand,
                  vector<bstr_t>& AttnOpt
                  ) {

   ICalendarMessagePtr iCalMsg(__uuidof(CalendarMessage));
   IConfigurationPtr   iConf(__uuidof(Configuration));
   IAttendeePtr        iAttn;
   IPersonPtr          iPer;

   try {
      iPer = iMbx;
   }
   catch(_com_error e ) {
      cerr << "Invalid or unbound Person object reference passed. " << endl;
      _com_issue_error(E_INVALIDARG);
   }

   iConf->Fields->Item[cdoSendEmailAddress]->Value = variant_t(iPer->Email);
   iConf->Fields->Item[cdoMailboxURL]->Value = variant_t(iMbx->BaseFolder);
   iConf->Fields->Update();

   iAppt->Configuration = iConf;

   typedef vector<bstr_t>::const_iterator CI;
   for(CI p = AttnMand.begin(); p != AttnMand.end(); p++) {
      iAttn = iAppt->Attendees->Add(bstr_t());
      iAttn->Address = _bstr_t(*p);
      iAttn->Role = cdoRequiredParticipant;
      cout << "Added " << bstr_t(*p) << " as required attendee to meeting" << endl;
   }

   for(p = AttnOpt.begin(); p != AttnOpt.end(); p++) {
      iAttn = iAppt->Attendees->Add(bstr_t());
      iAttn->Address = _bstr_t(*p);
      iAttn->Role = cdoOptionalParticipant;
      cout << "Added " << bstr_t(*p) << " as optional attendee to meeting" << endl;
   }

   try {
      iCalMsg = iAppt->CreateRequest();
      iCalMsg->Message->Send();
   }
   catch(_com_error e) {
      cerr << "Error creating and sending request" << endl;
      throw e;
   }

   try {
      iAppt->DataSource->Save();
   }
   catch(_com_error e) {
      cerr <<  "Error saving appointment!" << endl;
      throw e;
   }

}
Note By default, calendar messages are sent by using the Simple Mail Transport Protocol (SMTP) pick-up directory.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Addressing a Calendar Message

You can add attendees to a meeting by using the Attendees collection of the Appointment object. The Attendees collection can contain one or more attendees. You can use the same Attendee object to add each attendee.

When you create a CalendarMessage object requesting a meeting, the message is automatically addressed to each attendee in the Attendees collection.

To add attendees to an appointment

  1. Create an Attendee object.
  2. Set the properties of the Attendee object.
  3. Add each attendee by using the same Attendee object.

The following example shows how to add attendees to an appointment and then generate a meeting request:

Visual Basic

Dim iAppt      As New Appointment
Dim iAttendee  As Attendee

'Add a required attendee
Set iAttendee = iAppt.Attendees.Add
iAttendee.Address = "someone@microsoft.com"
iAttendee.Role = cdoRequiredParticipant

'Add an optional attendee
Set iAttendee = iAppt.Attendees.Add
iAttendee.Address = "another@microsoft.com"
iAttendee.Role = cdoOptionalParticipant
' ...

C++

IAppointmentPtr iAppt(__uuidof(Appointment));
IAttendeePtr iAttn;

//Add a required attendee
// Set e-mail address during addition step.
iAttn = iAppt->Attendees->Add(bstr_t(strEmailAddr));
iAttn->Role = cdoRequiredParticipant;
cout << "Attendee e-mail address (MAILTO:): " << iAttn->Address << endl;

//Add an optional attendee
iAttn = iAppt->Attendees->Add(bstr_t());
iAttn->Address = "another@microsoft.com";
iAttn->Role = cdoOptionalParticipant;
// ...

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Checking Free/Busy Status

Before you send a meeting request, you can check an attendee’s calendar to see when the attendee is available. The IAddressee.GetFreeBusy method returns a string of numbers that indicate the attendee's availability for a requested period of time.

Each number in the free/busy string represents an interval of time (every ½ hour in this example). Free time returns 0, Tentative returns 1, Busy returns 2, and Out of Office (OOF) returns 3. If appointments overlap, the highest number is returned. If no free/busy data is available for the interval, the value 4 is returned.

The following figure shows part of an attendee's calendar and the corresponding free/busy string.

To get an attendee's free/busy status for a specific time, you can create an Addressee object and execute the IAddressee.GetFreeBusy method. You can also get the free/busy status for longer intervals and parse the string to find times the attendee is free.

Note You must first call the IAddressee.CheckName method and resolve the addressee before you can use the IAddressee.GetFreeBusy method.

The following example returns the free/busy status of the specified user:

Visual Basic

' Reference to Microsoft ActiveX Data Objects 2.5 Library
' Reference to Microsoft CDO for Exchange 2000 Library

Function GetFreeBusyString(strUserUPN As String, dtStartDate As Date, dtEndDate As Date, Interval As Integer) As String

    Dim iAddr    As New CDO.Addressee
    Dim freebusy As String
    Dim Info     As New ADSystemInfo

    iAddr.EmailAddress = strUserUPN
    If Not iAddr.CheckName("LDAP://" & Info.DomainDNSName) Then
        ' handle error
    End If

    'Get the free/busy status in Interval minute intervals from dtStartDate to dtEndDate
    freebusy = iAddr.GetFreeBusy(dtStartDate, dtEndDate, Interval)
    GetFreeBusyString = freebusy

End Function

C++

/*
 Assume that the following paths are in your
 INCLUDE path.
 %CommonProgramFiles%\system\ado
 %CommonProgramFiles%\microsoft shared\cdo
*/

#import <msado15.dll> no_namespace
#import <cdoex.dll> no_namespace
#include <iostream.h>

bstr_t getFreeBusyString( const bstr_t& userUPN, const bstr_t& domainDNSName, DATE startDate, DATE endDate, long Interval) {

   IAddresseePtr iAddr(__uuidof(Addressee));

   iAddr->EmailAddress = userUPN;
   if(iAddr->CheckName(bstr_t("LDAP://") + domainDNSName, bstr_t(), bstr_t()) == VARIANT_FALSE) {
      cerr << "Error looking up name!" << endl;
      _com_issue_error(E_FAIL);
   }

    //Get the free/busy status in Interval minute intervals from startDate to endDate
   return iAddr->GetFreeBusy(startDate, endDate, Interval, bstr_t(), bstr_t(), bstr_t(), bstr_t());

}
Note An automated process in Microsoft® Exchange 2000 Server periodically updates the free/busy status of users. Microsoft® Outlook® updates the free/busy status of Outlook users. CDO synchronizes the Outlook free/busy cache with free/busy information from CDO clients. The free/busy status is not updated immediately when a meeting is added to a user's calendar. By default, three months’ worth of free/busy status is maintained in a system folder in the Web Storage System.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Publishing an Appointment

When you publish an appointment, the appointment is available to others without requiring a response from them. For example, you can publish your company’s holidays, charity drives, and upcoming conferences.

You can save a published appointment to a public folder or a file, or you can send a published appointment by e-mail. Published appointments have no attendees. To publish an appointment, perform the following steps:

  1. Create an Appointment object.
  2. Set the properties of the appointment.
  3. Create a CalendarMessage object derived from the Appointment object by using the IAppointment.Publish method.
  4. Send the CalendarMessage by using the IMessage methods and save the Appointment object by using the IDataSource.SaveToContainer method.

In the following example, an organizer publishes an appointment to the “team” alias and saves it to the TeamCalendar public folder.

Visual Basic

' Reference to Microsoft ActiveX Data Objects 2.5 Library
' Reference to Microsoft CDO for Exchange 2000 Library

Sub PublishMeetingToFolder(iAppt As CDO.Appointment, _
                            iMbx As IMailbox, _
                            strTeamCalendarFolderURL As String, _
                            strTeamEmail As String)

    Dim iCalMsg     As CalendarMessage
    Dim Config      As New Configuration
    Dim iPer        As CDO.Person
    Dim Conn        As New ADODB.Connection
    Conn.Provider = "ExOLEDB.DataSource"

    'Set the configuration fields
    Set iPer = iMbx
    Config.Fields(cdoSendEmailAddress) = iPer.Email
    Config.Fields(cdoMailboxURL) = iMbx.BaseFolder
    Config.Fields.Update

    With iAppt
        Set .Configuration = Config
        'Publish the appointment

        ' Get CalendarMessage and send to the team.
        Set iCalMsg = .Publish
        iCalMsg.Message.To = strTeamEmail
        iCalMsg.Message.Send

        'Save the appointment to a public folder
        Conn.Open strTeamCalendarFolderURL
        .DataSource.SaveToContainer strTeamCalendarFolderURL, Conn

    End With

End Sub

C++

/*
 Assume that the following paths are in your
 INCLUDE path.
 %CommonProgramFiles%\system\ado
 %CommonProgramFiles%\microsoft shared\cdo
*/

#import <msado15.dll> no_namespace
#import <cdoex.dll> no_namespace
#include <iostream.h>

void publishAppointmentToFolder(
                     const IAppointmentPtr& iAppt,
                     const IMailboxPtr& iMbx,
                     const bstr_t& strTeamCalendarFolderURL,
                     const bstr_t& strTeamEmail)
{

   ICalendarMessagePtr iCalMsg;
   IConfigurationPtr   iConf(__uuidof(Configuration));
   IPersonPtr          iPer;
   _ConnectionPtr      Conn(__uuidof(Connection));

   Conn->Provider = "ExOLEDB.DataSource";

   try {
      iPer = iMbx;
   }
   catch(_com_error e ) {
      cerr << "Invalid or unbound Person object reference passed. " << endl;
      _com_issue_error(E_INVALIDARG);
   }

   iConf->Fields->Item[cdoSendEmailAddress]->Value = variant_t(iPer->Email);
   iConf->Fields->Item[cdoMailboxURL]->Value = variant_t(iMbx->BaseFolder);
   iConf->Fields->Update();

   iAppt->Configuration = iConf;

   try {
      iCalMsg = iAppt->Publish();
      iCalMsg->Message->To = strTeamEmail;
      iCalMsg->Message->Send();

      // Save the appointment to a public folder
   }
   catch(_com_error e) {
      cerr << "Failed to send e-mail to " << strTeamEmail << endl;
      throw e;
   }

   try {
       Conn->Open(strTeamCalendarFolderURL, bstr_t(), bstr_t(), -1);
      iAppt->DataSource->SaveToContainer(strTeamCalendarFolderURL,
                              Conn,
                              adModeReadWrite,
                              adCreateNonCollection,
                              adOpenSource,
                              bstr_t(),
                              bstr_t());
   }
   catch(_com_error e) {
      cerr << "Failed to save appointment to folder at URL: " << strTeamCalendarFolderURL << endl;
      throw e;
   }

}

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Creating Recurring Appointments and Meetings

Recurring appointments and meetings occur more than once and follow a pattern in time. For example, a department meeting on the first Tuesday of each month can be defined as a recurring meeting.

In CDO, a single Appointment object and one or more RecurrencePattern objects represent a recurring appointment or meeting. The Appointment object defines the first appointment or meeting, and the RecurrencePattern objects define the pattern for additional appointments or meetings. You can also specify modifications to the pattern by using one or more Exception objects.

  1. Create an Appointment object.
  2. Set the properties of the first appointment or meeting.
  3. Create a RecurrencePattern object and add it to the Appointment's RecurrencePatterns collection. You do this by using the IRecurrencePatterns.Add method.
  4. Set the properties of the RecurrencePattern object to create the desired recurrence pattern.
  5. For meetings, create one or more Attendee objects and specify the attendees.
  6. For meetings, create a CalendarMessage object by using the IAppointment.CreateRequest method and send the message.
  7. Save the appointment to the organizer's calendar (optional).

The following example creates a recurring meeting and then invites the specified attendees to the meeting.

Visual Basic

' Reference to Microsoft ActiveX Data Objects 2.5 Library
' Reference to Microsoft CDO for Exchange 2000 Library

Sub CreateRecurringMeeting(ObjPer As CDO.Person, _
            ObjAppt As CDO.Appointment, _
            ObjFreq As CDO.CdoFrequency, _
            LngInterval As Long, _
            dtmEndDate As Date, _
            ObjMbx As IMailbox, _
            strAttnMandatory() As String, _
            strAttnOptional() As String)

    Dim ObjConfig As New Configuration
    Dim ObjRRule As IRecurrencePattern
    Dim ObjCalMsg As CalendarMessage
    Dim ObjAtten As New Attendee
    Dim StrCalendarURL As String
    Dim ObjConn As New ADODB.Connection

    ObjConn.Provider = "ExOLEDB.DataSource"

    'Set the configuration fields
    ObjConfig.Fields(cdoSendEmailAddress) = ObjPer.Email
    ObjConfig.Fields(CDO.cdoMailboxURL) = ObjMbx.BaseFolder
    ObjConfig.Fields.Update

    With ObjAppt
        .Configuration = ObjConfig

        'Create the RecurrencePattern Object
        Set ObjRRule = .RecurrencePatterns.Add("Add")

        'Define the recurrence pattern
        'Frequency such as cdoWeekly or cdoDaily
        ObjRRule.Frequency = ObjFreq
        'Interval, for example "2"
        ObjRRule.Interval = LngInterval
        'The pattern end date.
        ObjRRule.PatternEndDate = dtmEndDate

        'Add attendees
        Dim i As Long
        For i = LBound(strAttnMandatory) To UBound(strAttnMandatory) - 1
            Set ObjAtten = .Attendees.Add
            ObjAtten.Address = CStr(strAttnMandatory(i))
            ObjAtten.Role = cdoRequiredParticipant
        Next i

        For i = LBound(strAttnOptional) To UBound(strAttnOptional) - 1
            Set ObjAtten = .Attendees.Add
            ObjAtten.Address = CStr(strAttnOptional(i))
            ObjAtten.Role = cdoOptionalParticipant
        Next i

        'Create Meeting Request Message and Send (to attendees).
        Set ObjCalMsg = .CreateRequest

        'Save the appointment to the organizer's calendar
        ObjConn.Open ObjMbx.BaseFolder
        .Datasource.SaveToContainer ObjMbx.Calendar, ObjConn

        ObjCalMsg.Message.Send
    End With

End Sub

C++

/*
 Assume that the following paths are in your
 INCLUDE or Directories path:
 %CommonProgramFiles%\system\ado
 %CommonProgramFiles%\microsoft shared\cdo
*/

#import <msado15.dll> no_namespace
#import <cdoex.dll> no_namespace
#include <iostream.h>
#include <vector>
using namespace std;

void createRecurringMeeting(
                     IAppointmentPtr& iAppt,
                     IMailboxPtr& iMbx,
                     CdoFrequency Frequency,
                     long Interval,
                     DATE endDate,
                     vector<bstr_t>& AttnMand,
                     vector<bstr_t>& AttnOpt
                     )
{

   if(iAppt == NULL || iMbx == NULL)
      _com_issue_error(E_INVALIDARG);

   IConfigurationPtr iConf(__uuidof(Configuration));
   _ConnectionPtr Conn(__uuidof(Connection));
   IRecurrencePatternPtr RRULE;
   ICalendarMessagePtr iCalMsg;
   IAttendeePtr iAttn;
   IPersonPtr  iPer;

    Conn->Provider = "ExOLEDB.DataSource";

   try {
      iPer = iMbx;
   }
   catch(_com_error e ) {
      cerr << "Invalid or unbound Person object reference passed." << endl;
      _com_issue_error(E_INVALIDARG);
   }

   iConf->Fields->Item[cdoSendEmailAddress]->Value = variant_t(iPer->Email);
   iConf->Fields->Item[cdoMailboxURL]->Value = variant_t(iMbx->BaseFolder);
   iConf->Fields->Update();

   iAppt->Configuration = iConf;

    //Create the RecurrencePattern object
    RRULE = iAppt->RecurrencePatterns->Add("Add");

    /*
     Define the recurrence pattern
      Frequency, such as cdoWeekly or cdoDaily
   */
    RRULE->Frequency = Frequency;

    // Interval, for example "2"
    RRULE->Interval = Interval;

    // The pattern end date.
    RRULE->PatternEndDate = endDate;

   typedef vector<bstr_t>::const_iterator CI;
   for(CI p = AttnMand.begin(); p != AttnMand.end(); p++) {
      iAttn = iAppt->Attendees->Add(bstr_t());
      iAttn->Address = _bstr_t(*p);
      iAttn->Role = cdoRequiredParticipant;
      cout << "Added " << bstr_t(*p) << " as required attendee to meeting." << endl;
   }

   for(p = AttnOpt.begin(); p != AttnOpt.end(); p++) {
      iAttn = iAppt->Attendees->Add(bstr_t());
      iAttn->Address = _bstr_t(*p);
      iAttn->Role = cdoOptionalParticipant;
      cout << "Added " << bstr_t(*p) << " as optional attendee to meeting." << endl;
   }

   try {
      iCalMsg = iAppt->CreateRequest();
   }
   catch(_com_error e) {
      cerr << "Error creating the request" << endl;
      throw e;
   }

    //Save the appointment to the organizer's calendar
   try {
      Conn->Open(iMbx->BaseFolder, bstr_t(), bstr_t(), -1);
      iAppt->DataSource->SaveToContainer(
                        iMbx->Calendar,
                        Conn,
                        adModeReadWrite,
                        adCreateNonCollection,
                        adOpenSource,
                        bstr_t(),
                        bstr_t());
    }
   catch(_com_error e) {
      cerr << "Error saving recurring appointment to user's calendar folder." << endl;
      throw e;
   }

   try {
      iCalMsg->Message->Send();
   }
   catch(_com_error e) {
      cerr << "Error sending calendar message." << endl;
      throw e;
   }

}

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Specifying Exceptions to Recurring Appointments and Meetings

Exceptions are specific appointments that are added, modified, or deleted from the pattern of a recurring appointment or meeting. For example, if a recurring pattern generates a meeting that falls on a holiday, you can define an exception to that one instance of the recurring pattern.

CDO uses IRecurrencePattern objects and IException objects to define exceptions to recurring appointments and meetings. The following table shows how each object can be used.

Object | Type | Action
IRecurrencePattern | Add | Adds a set of instances.
IRecurrencePattern | Delete | Deletes a set of instances.
IException | Add | Adds a single instance.
IException | Delete | Deletes a single instance.
IException | Modify | Changes the properties of one or more instances (equivalent to a Microsoft® Outlook® exception).
  1. Create the recurring appointment or meeting.
  2. Create an Exception object by using the Add method on the Exceptions collection of the Appointment object, or create a RecurrencePattern object by using the Add method on the RecurrencePatterns collection.
  3. Set the properties of the Exception or RecurrencePattern object to specify appointment instances that are being added, deleted, or modified.

The following example creates a recurring meeting, deletes the meeting instance on November 26, 2000, and adds a meeting instance on November 29, 2000.

Visual Basic

' Reference to Microsoft ActiveX Data Objects 2.5 Library
' Reference to Microsoft CDO for Exchange 2000 Library

Function CreateApptWithException(iMbx As IMailbox) As CDO.Appointment

    Dim iAppt       As New Appointment
    Dim Config      As New Configuration
    Dim RRULE       As IRecurrencePattern
    Dim iCalMsg     As CalendarMessage
    Dim EXDATE      As IException
    Dim RDATE       As IException
    Dim Conn        As New ADODB.Connection
    Conn.Provider = "ExOLEDB.DataSource"

    With iAppt
        'Set the first appointment properties
        .StartTime = Now
        .EndTime = DateAdd("n", 60, Now)   ' 60 minute appointment starting now
        .Subject = "Read the Exchange SDK Docs."
        .Location = "My Office"

        'Create the RecurrencePattern object
        Set RRULE = .RecurrencePatterns.Add("Add")

        'Define the recurrence pattern
        RRULE.Frequency = cdoDaily  'use a daily pattern
        RRULE.Interval = 1  'every day
        RRULE.PatternEndDate = DateAdd("d", 7, Now) 'the last appointment, 7 days from now at this time.

        'Delete an appointment instance
        Set EXDATE = .Exceptions.Add("Delete")
        'The ID is the start time of the instance being deleted
        EXDATE.RecurrenceID = DateAdd("d", 7, Now) ' Except the 7th day...reschedule.

        'Add an appointment instance
        Set RDATE = .Exceptions.Add("Add")
        ' Start 2 hours later on the seventh day
        RDATE.StartTime = DateAdd("n", -60, DateAdd("d", 7, Now))
        RDATE.EndTime = DateAdd("d", 7, Now)

        'Save the appointment to the organizer's calendar
        Conn.Open iMbx.BaseFolder
        .DataSource.SaveToContainer iMbx.Calendar, Conn
    End With
    Set CreateApptWithException = iAppt

End Function

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Using Calendar Folder Query

The Web Storage System expands recurring appointments and meetings when the calendar folder is queried through a Structured Query Language (SQL) statement. The instances are expanded within the range specified by the query. For example, if you query a calendar folder for all entries in the month of November, the Web Storage System expands the November instances of all recurring appointments and meetings. Although appointments and meetings can be stored in any folder, the Web Storage System expands only recurring appointments and meetings that are stored in calendar folders.

To expand recurring appointments, query the calendar folder by using a SELECT statement. Use the WHERE clause of the SELECT statement to specify the range of dates that are expanded with each recurring appointment. The dates must be adjusted from local time to UTC (because dates are stored in UTC), then converted to International Standards Organization (ISO) format, and finally cast to the DateTime data type, as shown in the following query.

SELECT "DAV:href", "urn:schemas:calendar:dtend","urn:schemas:calendar:dtstart"
FROM scope('shallow traversal of """ & CalendarURL & """')
WHERE ("urn:schemas:calendar:dtstart" >= CAST("1999-10-25T16:00:00Z" as 'dateTime'))
AND ("urn:schemas:calendar:dtend" <= CAST("1999-10-30T01:00:00Z" as 'dateTime'))

There is a limitation of two years for calendar expansion queries. If the WHERE clause of a query specifies a range of more than two years between the start date and the end date, the query fails and returns a run-time error.

The following example shows how to query a calendar for a specific user. It prints the subject, start time, and end time of each appointment and meeting found. The example also includes functions to convert a date string to a different time zone and to the ISO format; you must change the time zone constants to the appropriate values for your clients.

Visual Basic

' Reference to Microsoft ActiveX Data Objects 2.5 Library
' Reference to Microsoft CDO for Exchange 2000 Library

Function QueryCalendarFolder(dtStartDate As Date, dtEndDate As Date, iMbx As IMailbox) As ADODB.Recordset

    Dim Rs          As New ADODB.Recordset
    Dim Rec         As New ADODB.Record
    Dim Conn        As New ADODB.Connection

    'Open the record set for the items in the calendar folder
    Conn.Provider = "ExOLEDB.DataSource"
    Conn.Open iMbx.Calendar
    Rec.Open iMbx.Calendar, Conn
    Set Rs.ActiveConnection = Rec.ActiveConnection

    Rs.Source = "SELECT ""DAV:href"", " & _
                      " ""urn:schemas:calendar:dtstart""," & _
                      " ""urn:schemas:calendar:dtend""," & _
                      " ""urn:schemas:calendar:duration""," & _
                      " ""urn:schemas:httpmail:subject"", " & _
                      " ""urn:schemas:calendar:instancetype""," & _
                      " ""urn:schemas:calendar:busystatus"" " & _
                " FROM scope('shallow traversal of """ & iMbx.Calendar & """')" & _
                " WHERE (""urn:schemas:calendar:dtstart"" >= CAST(""" & GetISODate(ConvertDate(dtStartDate)) & """ as 'dateTime')) AND " & _
                  "(""urn:schemas:calendar:dtend"" <= CAST(""" & GetISODate(ConvertDate(dtEndDate)) & """ as 'dateTime'))"

    Rs.Open

    Set QueryCalendarFolder = Rs
End Function

Function GetISODate(dtDate As Date)
    GetISODate = Format(CStr(dtDate), "yyyy-mm-ddThh:mm:ssZ")
End Function

Function ConvertDate(dtSrc As Date, _
                                   Optional dstTzId As CdoTimeZoneId = cdoPacific, _
                                   Optional srcTzId As CdoTimeZoneId = cdoPacific, _
                                   Optional srcTz As String = "", _
                                   Optional dstTz As String = "") As Date

    Dim obAppt      As New CDO.Appointment
    Dim obConfig    As New CDO.Configuration
    Dim bTz         As Boolean

    obAppt.Configuration = obConfig

    bTz = ((srcTz <> "") Or (dstTz <> ""))

    If (Not bTz) Then
        obConfig.Fields(cdoTimeZoneIDURN) = srcTzId
    Else
        obConfig.Fields(cdoTimeZoneURN) = srcTz
    End If
    obConfig.Fields.Update

    obAppt.StartTime = dtSrc

    If (Not bTz) Then
        obConfig.Fields(cdoTimeZoneIDURN) = dstTzId
    Else
        obConfig.Fields(cdoTimeZoneURN) = dstTz
    End If
    obConfig.Fields.Update

    ConvertDate = obAppt.StartTime

End Function

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Adding Attachments to Appointments and Meetings

You can add attachments to appointments and meetings. For example, you could attach an image of a map to a meeting to show where the meeting is located.

Attachments are added by using the Attachments collection of the Appointment object. Attachments are saved with the Appointment object in the Web Storage System.

  1. Create the Appointment object and set its properties.
  2. Create the attachment body part by calling the Add method on the attachments collection.
  3. Set the content type and content transfer encoding fields of the body part.
  4. Get the default stream from the attachment body part.
  5. Load the file being attached into the default stream, and save it back to the attachment body part.
  6. For meetings, create a calendar message, add attendees, and send the meeting request.
  7. Save the appointment or meeting to the organizer's calendar folder (optional).

The following example shows how to add the attachment d:\maps\directions.gif to a meeting.

Visual Basic

' Reference to Microsoft ActiveX Data Objects 2.5 Library
' Reference to Microsoft CDO for Exchange 2000 Library

Sub AddAttachmentToAppt(iAppt As CDO.Appointment, strFilePath As String, strContentType As String, strEncoding As String)

    Dim iBp As CDO.IBodyPart
    Set iBp = iAppt.Attachments.Add
    'Set the fields for the attachment
    Set Flds = iBp.Fields
    Flds.Item("urn:schemas:mailheader:content-type") = strContentType
    Flds.Item("urn:schemas:mailheader:content-transfer-encoding") = strEncoding
    Flds.Update

    'Get the stream interface on the body part
    Set Stm = iBp.GetDecodedContentStream

    'Load the attachment file into the stream and flush
    '  the stream to save it back to the body part
    Stm.LoadFromFile strFilePath
    Stm.Flush

End Sub

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Processing a Calendar Message

When a meeting organizer sends a meeting request, Microsoft® Exchange 2000 Server stores the calendar message in the recipient's inbox. Responses to meeting requests, meeting updates, and cancellations are all received as calendar messages in the inbox. You can use Microsoft® ActiveX® Data Objects (ADO) and CDO to retrieve calendar messages from the inbox and process them.

You can identify an item in an Exchange 2000 Server folder by the item's content class. The content class is a property of items in the Web Storage System. The content class of calendar messages is contained in the DAV:contentclass field of the message. All calendar messages have the content class urn:content-classes:calendarmessage.

You typically open calendar messages by using the ICalendarPart.GetUpdatedItem method. This method checks the Web Storage System to verify if the meeting in the calendar message already exists. If the meeting already exists, the calendar message is probably an update to that meeting. The GetUpdatedItem method returns an Appointment object in memory that contains the most current meeting information, either from the Web Storage System or the calendar message. When you save the meeting, it overwrites the existing meeting in the Web Storage System.

Note If the calendar part contains an exception to an existing recurring meeting, the GetUpdatedItem method returns the exception in memory. If you accept or decline the exception, the meeting response is based on the exception. However, when you call the IDataSource.Save method on the exception, it merges the exception into the master recurring meeting and saves the updated master to the Web Storage System.

This topic explains how to identify and open calendar messages. Other topics in this section explain how to process the calendar message after it has been opened.

To open calendar messages in the inbox

  1. Open the inbox folder by using a ADO database (ADODB) record.
  2. Open an ADO Recordset containing the items in the inbox. Use a SELECT statement to include the item URL and content class in the record set. Specify a WHERE clause to select only calendar messages.
  3. Get the URL of the message from the record set, and then open the URL by using a CDO CalendarMessage object.
  4. Open each calendar part in the calendar parts collection by using a CDO Appointment object, and process the Appointment object as needed.
  5. Delete the calendar message from the inbox (optional).

The following example gets all calendar messages from the inbox of a specific user. It prints the subject of each calendar part and deletes the message. The examples under other topics in this section explain how to process the calendar parts.

Visual Basic

' Reference to Microsoft ActiveX Data Objects 2.5 Library
' Reference to Microsoft CDO for Exchange 2000 Library

Sub ProcessCalMsgs(iMbx As IMailbox)

    Dim Rs As ADODB.Recordset
    Set Rs = QueryInboxFolderForCalMsgs(iMbx)
    Debug.Print Rs.RecordCount
    While Not Rs.EOF
        Debug.Print Rs(0)
        Debug.Print Rs(1)
        ProcessCalMsg Rs(0), Conn, iMbx, False
        Rs.MoveNext
    Wend

End Sub

Function QueryInboxFolderForCalMsgs(iMbx As IMailbox) As ADODB.Recordset

    Dim Rs          As New ADODB.Recordset
    Dim Rec         As New ADODB.Record
    Dim Conn        As New ADODB.Connection

    'Open the record set for the items in the calendar folder
    Conn.Provider = "ExOLEDB.DataSource"
    Conn.Open iMbx.BaseFolder
    Rec.Open iMbx.Inbox, Conn
    Set Rs.ActiveConnection = Rec.ActiveConnection

    Rs.Source = "SELECT ""DAV:href"", " & _
                " ""DAV:contentclass"", " & _
                " ""urn:schemas:httpmail:subject"" " & _
                " FROM scope('shallow traversal of """ & iMbx.Inbox & """')" & _
                " WHERE ""DAV:ishidden"" = False AND ""DAV:isfolder"" = False AND ""DAV:contentclass"" = 'urn:content-classes:calendarmessage'"
    Rs.Open

    Set QueryInboxFolderForCalMsgs = Rs
End Function

Sub ProcessCalMsg(itemURL As String, Conn As ADODB.Connection, iMbx As CDO.IMailbox, fDelete As Boolean)

    Dim iCalMsg      As New CalendarMessage
    Dim iAddre       As New Addressee
    Dim iCalPart     As ICalendarPart
    Dim iAppt        As Appointment
    Dim iDsrc        As CDO.IDataSource
    Dim Index        As Integer
    Dim Rec As New ADODB.Record

    Dim Config As New CDO.Configuration
    Config("CalendarLocation") = iMbx.Calendar
    Config.Fields.Update

    Set iCalMsg.Configuration = Config
    iCalMsg.DataSource.Open itemURL, Conn, adModeReadWrite

    'Get each calendar part
    For Each iCalPart In iCalMsg.CalendarParts
      Set iAppt = iCalPart.GetUpdatedItem
      Debug.Print "Subject: " & iAppt.Subject

      'Process the appointment as necessary
      Select Case iCalPart.CalendarMethod
        Case "REQUEST"
            ' Handle a meeting request
        Case "REPLY"
            ' Handle meeting request reply
        Case "CANCEL"
            ' Handle cancelled meeting.
      End Select
    Next iCalPart

    'If flagged, delete the calendar message from the inbox
    If fDelete Then
        Rec.Open itemURL, Conn, adModeReadWrite
        Debug.Print iMbx.DeletedItems
        Rec.DeleteRecord
        ' Or move the Record:
        ' Rec.MoveRecord , iMbx.DeletedItems, , , adMoveOverWrite
    End If
End Sub

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Responding to a Meeting Request

When you receive a meeting request in your inbox, you can accept it, accept it tentatively, reject it, or delete it. You typically save the meeting to your calendar folder after accepting the response.

Meeting requests are calendar messages that are identified by the ICalendarPart.CalendarMethod value REQUEST.

The CDO Appointment object provides three methods for responding to meeting requests: Accept, AcceptTentative, and Decline. Each method returns a CalendarMessage object that is addressed to the meeting requestor. Each method also updates the status of the meeting in memory so that if you save the meeting to your calendar, the status corresponds to the response you sent. You can also modify the message before sending it.

Note None of the response methods changes the meeting request message in the inbox. Typically, the program deletes the meeting request message after a response is sent.

To respond to a meeting request:

  1. Open each meeting in the calendar message as shown in Processing a Calendar Message.
  2. Based on the programming logic or user input, call the appropriate response method: Accept, AcceptTentative, or Decline.
  3. Make any desired changes to the response message (optional).
  4. Call the ICalendarMessage.Message.Send method to send the response.
  5. Save the meeting to the calendar folder.
  6. When you have finished processing all meetings in a calendar message, delete the message from the inbox.

The following example checks the inbox of a specific user. It accepts any meeting request with the word "lunch" in the subject line, and declines all other meetings. Then it deletes the calendar message from the inbox.

Visual Basic

Note The following example uses a file URL with the Exchange OLE DB (ExOLEDB) provider. The ExOLEDB provider also supports the HTTP URL scheme. Using the HTTP URL scheme allows both client and server applications to use a single URL scheme.
' Reference to Microsoft ActiveX Data Objects 2.5 Library
' Reference to Microsoft CDO for Exchange 2000 Library

Dim InboxURL     As String
Dim CalendarURL  As String
Dim itemURL      As String
Dim Rs           As New ADODB.Recordset
Dim Rec          As New ADODB.Record
Dim iCalMsg      As New CalendarMessage
Dim iCalMsg2     As CalendarMessage
Dim iCalPart     As ICalendarPart
Dim iAppt        As Appointment
Dim Index        As Integer
Dim ContentClass As String
Dim Config       As New Configuration

InboxURL = "file://./backofficestorage/" & DomainName & "/MBX/" & Username & "/inbox/"
CalendarURL = "file://./backofficestorage/" & DomainName & "/MBX/" & Username & "/calendar/"

'Set the configuration fields for the appointment objects
Config.Fields(cdoSendEmailAddress) = Username & "@" & DomainName
Config.Fields.Update

'Open the record set for the calendar messages in the inbox folder
Rec.Open InboxURL
Set Rs.ActiveConnection = Rec.ActiveConnection
Rs.Source = "SELECT ""DAV:href"",""DAV:contentclass"" " & _
  "FROM scope('shallow traversal of """ & InboxURL & """')" & _
  "WHERE (""DAV:contentclass"" = 'urn:content-classes:calendarmessage')"
Rs.Open

'Enumerate the record set and process each calendar message
Rs.MoveFirst
Do Until Rs.EOF
  'Open the calendar message
  itemURL = Rs.Fields(CdoDAV.cdoHref).Value
  iCalMsg.DataSource.Open itemURL, , adModeReadWrite
  iCalMsg.Configuration = Config
  'Get each calendar part
  For Index = 1 To iCalMsg.CalendarParts.Count
    Set iCalPart = iCalMsg.CalendarParts(Index)
    Set iAppt = iCalPart.GetUpdatedItem(CalendarURL)
    Select Case iCalPart.CalendarMethod
      Case "REQUEST"
        'Accept any meeting with "lunch" in the subject text
        If InStr(1, iAppt.Subject, "lunch", 1) Then
          Set iCalMsg2 = iAppt.Accept
        Else
          Set iCalMsg2 = iAppt.Decline
        End If
        'Save the meeting
        iAppt.DataSource.SaveToContainer CalendarURL
        'Send the response
        iCalMsg2.Message.Send
      Case Else
        'See the other examples in this section
    End Select

  Next Index
  'Delete the calendar message
  Rs.Delete

Rs.MoveNext
Loop

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Processing Meeting Responses

The organizer of a meeting receives the responses to meeting requests from attendees. The organizer then needs to process all the responses to update their status. Because attendees can invite other attendees, a meeting organizer should be able to process responses from attendees the organizer did not invite.

When you call the ICalendarPart.GetUpdatedItem method, CDO searches your calendar folder for an existing meeting that matches a meeting in the calendar part. CDO builds an appointment object in memory that contains the latest information from the saved meeting and the new meeting. The response to your meeting request (accepted, declined, or tentative) is merged into the existing meeting. When you save the appointment object in memory using the Datasource.Save method, the meeting in your calendar folder contains the updated attendee status.

Meeting responses are calendar messages identified by the ICalendarPart.CalendarMethod value "REPLY."

To process meeting responses:

  1. Open each meeting in the calendar message as shown in Processing a Calendar Message.
  2. Save the meeting returned by GetUpdatedItem.
  3. Delete the calendar message after processing all calendar parts.

The code in the following example checks the inbox of a specific user. It then opens all meeting responses and saves the updated attendee status. Finally, it deletes the calendar message from the inbox.

Visual Basic

' Reference to Microsoft ActiveX Data Objects 2.5 Library
' Reference to Microsoft CDO for Exchange 2000 Library

Sub ProcessResponse(iCalMsg As CDO.CalendarMessage, iMbx As IMailbox)

    Dim Rec          As New ADODB.Record
    Dim Conn         As New ADODB.Connection
    Dim iCalMsg      As New CalendarMessage
    Dim iCalPart     As ICalendarPart
    Dim iAppt        As CDO.Appointment

    Conn.Provider = "ExOLEDB.DataSource"
    Conn.Open iMbx.BaseFolder

    For Each iCalPart In iCalMsg.CalendarParts
        Set iAppt = iCalPart.GetUpdatedItem(iMbx.Calendar)
        Select Case iCalPart.CalendarMethod
            Case "REPLY" ' Make sure this is a reply
                iAppt.DataSource.Save
        End Select
    Next

End Sub

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Processing Meeting Cancellations

As the organizer of a meeting, you can send a calendar message to cancel a meeting. Cancellation messages are calendar messages identified by the ICalendarPart.CalendarMethod value "CANCEL."

Instead of deleting the meeting from their calendars, attendees save the updated appointment object that has a MeetingStatus property set to Cancelled. Calendar client programs typically do not display canceled meetings. For example, Microsoft® Outlook® ignores canceled meetings when building calendar views. CDO does not automatically delete canceled meetings from the Web Storage System.

To process meeting cancellations

  1. Open each meeting in the calendar message as shown in Processing a Calendar Message.
  2. Save the meeting returned by the GetUpdatedItem method.
  3. Delete the calendar message after processing all calendar parts.

The code in the following example checks the inbox of user12 on a Microsoft® Exchange 2000 Server named exsvr3, in the exchange.microsoft.com domain. It opens all meeting cancellations and saves the updated meeting. Then it deletes the calendar message from the inbox.

Visual Basic

Note The following example uses a file URL with the Exchange OLE DB (ExOLEDB) provider. The ExOLEDB provider also supports the HTTP URL scheme. Using the HTTP URL scheme allows both client and server applications to use a single URL scheme.
Dim InboxURL     As String
Dim CalendarURL  As String
Dim ItemURL      As String
Dim Rs           As New ADODB.Recordset
Dim Rec          As New ADODB.Record
Dim iCalMsg      As New CalendarMessage
Dim iCalPart     As     ICalendarPart
Dim iAppt        As     Appointment
Dim Index        As     Integer
Dim ContentClass As     String
Dim Config       As New Configuration

InboxURL = "file://./backofficestorage/exchange.microsoft.com/MBX/user12/inbox/"
CalendarURL = "file://./backofficestorage/exchange.microsoft.com/MBX/user12/calendar/"

'Set the configuration fields for the appointment objects
Config.Fields(cdoSendEmailAddress) = "user12@exchange.microsoft.com"
Config.Fields("CalendarLocation") = CalendarURL
Config.Fields.Update

'Open a recordset for the items in the inbox folder
Rec.Open InboxURL
Set Rs.ActiveConnection = Rec.ActiveConnection
Rs.Source = "select ""DAV:href"",""DAV:contentclass"" from scope('shallow traversal of """ & InboxURL & """')"
Rs.Open

'Enumerate the recordset, checking each item's content class
Rs.MoveFirst
Do Until Rs.EOF
  'get the content class of each item
  ContentClass = Rs.Fields("DAV:contentclass").Value
  'test content class for calendar message
  If ContentClass = "urn:content-classes:calendarmessage" Then
    'open calendar message
    ItemURL = Rs.Fields(CdoDAV.cdoHref).Value
    iCalMsg.DataSource.Open ItemURL
    iCalMsg.Configuration = Config
    Debug.Print "Message subject: " & iCalMsg.Message.Subject
    'get each calendar part
    For Index = 1 To iCalMsg.CalendarParts.Count
      Set iCalPart = iCalMsg.CalendarParts(Index)
      Set iAppt = iCalPart.GetUpdatedItem
      Select Case iCalPart.CalendarMethod
        Case "CANCEL"
         'Save the appointment
         iAppt.DataSource.Save
        Case Else
          'see other examples in this section
      End Select

    Next Index

    'Delete the calendar message
    Rs.Delete
  End If

Rs.MoveNext
Loop

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Processing Recurring Meeting Exceptions

There are two ways to process exceptions in recurring meetings. If the meeting does not contain exceptions with a RecurrenceIDRange property value of ThisAndFuture or ThisAndPrior, you can process each exception exactly once. This is an efficient way to process exceptions.

If the meeting contains ThisAndFuture or ThisAndPrior exceptions, you must loop through the exceptions multiple times. This is less efficient.

The code in the following example works for exceptions that do not contain ThisAndFuture or ThisAndPrior values:

Visual Basic

Dim recurid As Date
  Dim obExAppt As CDO.Appointment
  Dim obReq As CDO.CalendarMessage
  Dim obEx As CDO.IException

  For Each obEx In obAppt.Exceptions
    'To make sure we process next exception if we can't process this one
    On Error GoTo NextException
    If obEx.Type = "Modify" Then
      recurid = obEx.RecurrenceID
      'Found an exception: process it
      Set obExAppt = obAppt.GetFirstInstance(recurid, recurid)
      Set obReq = obExAppt.CreateRequest ' OR Invite OR Cancel, etc.
      obReq.Message.Send
  End If
NextException:
  End

The code in the following example works for exceptions that contain ThisAndFuture or ThisAndPrior values:

Visual Basic

While (1)
  On Error GoTo NextInstance
  obExAppt = obAppt.GetNextInstance
  If obExAppt.Fields("urn:schemas:calendar:instancetype") = cdoException Then
    Found an exception: process it
    Set obExAppt = obAppt.GetFirstInstance(recurid, recurid)
    Set obReq = obExAppt.CreateRequest ' OR Invite OR Cancel, etc.
    obReq.Message.Send
    End If
NextInstance:
  'Check for err.Number = DISP_E_BADINDEX: 0x8002000b (winerror.h)
  If Err.Number = 2147614731# Then GoTo Quit
  End
Quit:

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Updating Appointments and Meetings

You can update the properties and fields of an appointment or meeting that is saved in your calendar folder. For appointments, you overwrite the original appointment in the Microsoft Web Storage System with the updated appointment. For meetings, in addition to saving the changes to the Web Storage System, you must send the updates to attendees. If you are not the meeting organizer and you update a meeting in your calendar folder, any updates you accept from the meeting organizer overwrite your updates.

To update appointments or meetings

  1. Open an appointment or meeting in the Calendar folder as shown in Getting Appointments and Meetings from Folders in Exchange. Be sure to open the appointment in read/write mode by using adModeReadWrite.
  2. Change the properties and fields of the appointment or meeting.
  3. Save the appointment or meeting to the calendar folder using the IAppointment.Datasource.Save method.

The code in the following example checks all of the appointments and meetings in the calendar of user12 on the Microsoft® Exchange 2000 Server in the exchange.microsoft.com domain. It changes any appointment or meeting scheduled in the "Flamingo Room" to the "Mount Rainier Room" and saves the appointment.

Visual Basic

Note The following example uses a file URL with the Exchange OLE DB (ExOLEDB) provider. The ExOLEDB provider also supports the HTTP URL scheme. Using the HTTP URL scheme allows both client and server applications to use a single URL scheme.
Dim CalendarURL As     String
Dim ItemURL     As     String
Dim Rs          As New ADODB.Recordset
Dim Rec         As New ADODB.Record
Dim Conn        As New ADODB.Connection
Dim iAppt       As New Appointment
Dim Target      As     String
Dim NewValue    As     String
Dim Location    As     String

Target = "Flamingo Room"
NewValue = "Mount Rainier Room"

  'Using the Exchange OLE DB provider
  CalendarURL = "file://./backofficestorage/user12.extest.microsoft.com/MBX/user12/calendar/"

'Open a record set for the items in the calendar folder
Rec.Open CalendarURL
Set Rs.ActiveConnection = Rec.ActiveConnection
Rs.Source = "SELECT ""DAV:href"", ""urn:schemas:calendar:location"" from scope('shallow traversal of """ & CalendarURL & """')"
Rs.Open

'Enumerate the record set, checking each item's location
Rs.MoveFirst
Do Until Rs.EOF
  'get the location of each item
  Location = Rs.Fields(CdoCalendar.cdoLocation).Value
  'test for desired location
  If (Location = Target) Then
    'open appointment in read/write mode and update the location property
    ItemURL = Rs.Fields(CdoDAV.cdoHref).Value
    iAppt.DataSource.Open ItemURL, , adModeReadWrite
    iAppt.Location = NewValue
    iAppt.DataSource.Save
  End If
  Rs.MoveNext
Loop

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Getting Appointments and Meetings from Folders in Exchange

Microsoft® Exchange 2000 Server stores appointments and meetings in a user's calendar folder or in a public folder. By using a CDO Appointment object, you can open, view, and modify appointments and meetings in the Web Storage System. Individual appointments and meetings are stored as single items in the Web Storage System.

Recurring appointments are expanded into individual instances when the calendar folder is queried in the Web Storage System. If you want to modify one or more instances of a recurring appointment, you can modify the master appointment. You can also modify the individual instances directly. The urn:schemas:calendar:instancetype field identifies master recurring appointments, recurring instances, single appointments, or exceptions to recurring appointments.

Although appointments and meetings can be stored in any Exchange folder, the Web Storage System expands only recurring appointments and meetings that are stored in calendar folders.

To get appointments from a calendar folder:

  1. Open the calendar folder using a Microsoft® ActiveX® Data Objects (ADO) database (ADODB) record.
  2. Open an ADODB record set containing the items in the calendar folder. Use a SELECT statement to include the item URL and the appointment date or other desired fields in the record set. To expand recurring meetings, include a WHERE clause in the SELECT statement that specifies the range of dates where recurring instances are expanded.
  3. Enumerate the record set, and then test each item's fields, as appropriate.
  4. For appointments that match your selection criteria, get the URL from the record set, and then open the URL using a CDO Appointment object.
  5. Process the Appointment objects as needed.

The code in the following example lists appointments in the calendar folder of user12, on the Exchange 2000 Server named exsvr3 in the exchange.microsoft.com domain. The code example selects appointments within a specific date range that have the subject "Department Meeting." It also prints the start and end times of the appointment, the subject, and the instance type.

Visual Basic

Note The following example uses a file URL with the Exchange OLE DB (ExOLEDB) provider. The ExOLEDB provider also supports the HTTP URL scheme. Using the HTTP URL scheme allows both client and server applications to use a single URL scheme.
Dim CalendarURL    As     String
Dim ItemURL        As     String
Dim Rs             As New ADODB.Recordset
Dim Rec            As New ADODB.Record
Dim Conn           As New ADODB.Connection
Dim iAppt          As New Appointment
Dim dateStartDate  As     Date
Dim Subject        As     String

CalendarURL = "file://./backofficestorage/exchange.microsoft.com/MBX/user12/calendar/"

'Open a record set for the items in the calendar folder
Rec.Open CalendarURL
Set Rs.ActiveConnection = Rec.ActiveConnection
Rs.Source = "SELECT ""DAV:href"", " & _
                  " ""urn:schemas:httpmail:subject"", " & _
                  " ""urn:schemas:calendar:dtstart"", " & _
                  " ""urn:schemas:calendar:dtend"" " & _
            "FROM scope('shallow traversal of """ & CalendarURL & """') " & _
            "WHERE (""urn:schemas:calendar:dtstart"" >= CAST(""1999-08-01T08:00:00Z"" as 'dateTime')) " & _
            "AND (""urn:schemas:calendar:dtend"" <= CAST(""1999-09-01T08:00:00Z"" as 'dateTime'))"
Rs.Open

'Enumerate the record set, checking each item's subject
Rs.MoveFirst
Do Until Rs.EOF
    'get the subject of each item
    Subject = Rs.Fields(CdoHTTPMail.cdoSubject).Value
    If Subject = "Department Meeting" Then
        'open appointment
        ItemURL = Rs.Fields(CdoDAV.cdoHref).Value
        iAppt.DataSource.Open ItemURL
        Debug.Print iAppt.StartTime & " - " & iAppt.EndTime
        Debug.Print "Subject: " & iAppt.Subject
        'print the type of appointment
        Select Case iAppt.Fields(CdoCalendar.cdoInstanceType).Value
            Case cdoSingle
                Debug.Print "Single appointment"
            Case cdoMaster
                Debug.Print "Master recurring appointment"
            Case cdoInstance
                Debug.Print "Instance of recurring appointment"
            Case cdoException
                Debug.Print "Exception to recurring appointment"
            Case Else
                Debug.Print "Unknown"
        End Select
    End If

    Rs.MoveNext

Loop

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Sending Meeting Updates

If you are the organizer of a meeting, you can send updates to the attendees of the meeting using a calendar message. CDO returns an error if you call the IAppointment.CreateRequest method for a meeting of which you are not the organizer.

Attendees process the update messages the same way they process any other calendar message. The ICalendarMessage.CalendarParts.GetUpdatedItem method compares the new calendar message with the existing meeting. It returns an Appointment object that can be saved to the calendar folder. The updated meeting overwrites the existing meeting. For more information on processing meeting updates, see Responding to a Meeting Request.

To send meeting updates

  1. Open the meeting, and then update the desired properties and fields as shown in Updating a Appointments and Meetings. Verify that you are the organizer of the meeting.
  2. Set the meeting configuration, and then create a Calendar Message object using the IAppointment.CreateRequest method. For a published appointment, use the Publish method instead of the CreateRequest method.
  3. Add any text you want to the Calendar Message object.
  4. Send the Calendar Message using the IMessage.Send method.
  5. Save the meeting update to the calendar folder.

The code in the following example checks all of the meetings in the calendar of user12, located on server exsvr3 in the exchange.microsoft.com domain. For meetings originated by user12, this code changes any meeting in the "Flamingo Room" to the "Mount Rainier Room" and sends an update to all attendees.

Visual Basic

Note The following example uses a file URL with the Exchange OLE DB (ExOLEDB) provider. The ExOLEDB provider also supports the HTTP URL scheme. Using the HTTP URL scheme allows both client and server applications to use a single URL scheme.
Dim CalendarURL As     String
Dim ItemURL     As     String
Dim Rec         As New ADODB.Record
Dim Rs          As New ADODB.Recordset
Dim iDsrc       As     CDO.IDataSource
Dim iAtnds      As     CDO.IAttendees
Dim Config      As New CDO.Configuration
Dim iAppt       As New CDO.Appointment
Dim iCalMsg     As     CDO.CalendarMessage
Dim iMsg        As     CDO.Message
Dim Target      As     String
Dim NewValue    As     String
Dim Location    As     String
Dim Address     As     String
Dim Index       As     Integer

Target = "Flamingo Room"
NewValue = "Mount Rainier Room"

  'Using the Exchange OLE DB provider
  CalendarURL = "file://./backofficestorage/exchange.microsoft.com/MBX/user12/calendar/"

'Set the configuration for the message
Config.Fields(cdoSendEmailAddress) = "user12@exchange.microsoft.com"
Config.Fields("CalendarLocation") = CalendarURL
Config.Fields.Update

'set address of user for comparing with attendee value
Address = "MAILTO:" & Config.Fields(cdoSendEmailAddress)

'Open a record set for the items in the calendar folder
Rec.Open CalendarURL
Set Rs.ActiveConnection = Rec.ActiveConnection
Rs.Source = "SELECT ""DAV:href"", ""urn:schemas:calendar:location"" from scope('shallow traversal of """ & CalendarURL & """')"
Rs.Open

'Enumerate the record set, checking each item's location
Rs.MoveFirst
Do Until Rs.EOF
  'get the location of each item
  Location = Rs.Fields(CdoCalendar.cdoLocation).Value
  'test for organizer and desired location
  If (Location = Target) Then
    'open appointment in read/write mode
    ItemURL = Rs.Fields(CdoDAV.cdoHref).Value
    Set iDsrc = iAppt
    iDsrc.Open ItemURL, , adModeReadWrite
    'verify this user is organizer by checking attendee property
    Set iAtnds = iAppt.Attendees
    'If appointment has attendess and this user is organizer send an update
    'otherwise just save update to calendar
    If iAtnds.Count > 1 Then
      For Index = 1 To iAtnds.Count
        If iAtnds.Item(Index).IsOrganizer And iAtnds.Item(Index).Address = Address Then
          'update the appointment location
          iAppt.Location = NewValue
          'save the appointment
          iDsrc.Save
          'set the configuration
          iAppt.Configuration = Config
          'create a calendar message
          Set iCalMsg = iAppt.CreateRequest
          'send the update to the attendees
          Set iMsg = iCalMsg.Message
          iMsg.TextBody = "Automated update - please note new location"
          iMsg.Send
        End If 'user is organizer
      Next Index
    Else 'appointment has only one attendee
      iAppt.Location = NewValue
      iDsrc.Save
    End If 'appointment has attendees
  End If 'location = target
  Rs.MoveNext
Loop

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Canceling Appointments and Meetings

There are four possible scenarios for canceling appointments and meetings:

  • The organizer cancels an appointment.
  • The organizer cancels a meeting or removes some attendees from a meeting.
  • The organizer cancels a single instance or all instances of a recurring meeting or appointment.
  • The attendee declines a previously accepted meeting.

Only the organizer of a meeting can cancel that meeting. However, attendees can remove themselves from a meeting by sending a decline response (even if they previously accepted it). The following sections describe each of these scenarios in detail.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Canceling an Appointment

To cancel an appointment, delete the appointment from the calendar folder. It is a good idea to verify that you are deleting an appointment and not a meeting by checking the attendee count (an appointment has no attendees). Unlike Microsoft® Outlook®, CDO does not warn you to notify attendees when you delete a meeting (see Canceling a Meeting).

To cancel an appointment

  1. Open the calendar folder by using an Microsoft® ActiveX® Data Objects (ADO) database (ADODB) record set.
  2. Locate the appointment that you want to delete. Open the appointment, and then check the attendee count to verify that there are no other attendees.
  3. Delete the appointment using the Recordset.Delete method.

The code in the following example gets all of the appointments with the subject "Documentation Review Meeting" in the calendar of a specific user. It then verifies that each appointment has no other attendees, and deletes it.

Visual Basic

' Reference to Microsoft ActiveX Data Objects 2.5 Library
' Reference to Microsoft CDO for Exchange 2000 Library

Sub CancelAppt(iAppt As CDO.Appointment, iMbx As IMailbox)

    Dim Conn        As New ADODB.Connection
    Dim iPer        As New CDO.Person
    Dim Rec         As New ADODB.Record

    Conn.Provider = "ExOLEDB.DataSource"
    Conn.Open iMbx.BaseFolder
    Rec.Open iAppt.DataSource.SourceURL, Conn, adModeReadWrite
    Rec.DeleteRecord
    Rec.Close

End Sub

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Canceling a Meeting

The organizer of a meeting can cancel a meeting and notify all of the attendees. To do so, the organizer changes the meeting status to Canceled and then sends an updated Calendar Message to the attendees.

The organizer can also remove some of the attendees from the meeting without canceling the entire meeting. To remove only some of the attendees, the organizer specifies the attendees' e-mail addresses in the string passed to the IAppointment.Cancel method. To cancel the entire meeting, the organizer calls the Cancel method without any parameters.

To cancel a meeting

  1. Open the calendar folder by using an Microsoft® ActiveX® Data Objects (ADO) database (ADODB) record set.
  2. Locate the meeting that you want to delete, and then open it using an Appointment object. Verify that you are the organizer. Be sure to open the appointment in read/write mode by using adModeReadWrite.
  3. Create a Calendar Message object using the IAppointment.Cancel method. Pass a list of attendees to be removed, or to cancel the entire meeting, do not pass any parameters.
  4. Add text to the Calendar Message object, if necessary.
  5. Send the Calendar Message object using the IMessage.Send method.
  6. Delete the canceled meeting from the calendar folder (optional).

The code in the following example gets all the meetings with the subject "Documentation Review Meeting" in the calendar of a specific user. It verifies that the user is the organizer, sends the cancellation message to the attendees, and then deletes the meeting from the calendar folder.

Visual Basic

' Reference to Microsoft ActiveX Data Objects 2.5 Library
' Reference to Microsoft CDO for Exchange 2000 Library

Sub CancelMeeting(iAppt As CDO.Appointment, iMbx As IMailbox)

    Dim Conn        As New ADODB.Connection
    Dim iPer        As New CDO.Person
    Dim iCalMsg     As CDO.CalendarMessage
    Dim Config      As CDO.Configuration

    Conn.Provider = "ExOLEDB.DataSource"
    Conn.Open iMbx.BaseFolder

    Set iCalMsg = iAppt.Cancel
    With iCalMsg
        Set Config = .Configuration
        Config(cdoSendUsingMethod) = cdoSendUsingExchange
        Config(cdoMailboxURL) = iMbx.BaseFolder
        Config(cdoActiveConnection) = Conn
        Config.Fields.Update
        .Message.TextBody = "Sorry, the meeting has been cancelled"
        .Message.Send
    End With
    'Delete the appointment from the calendar folder (optional)
End Sub

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Canceling Recurring Appointments and Meetings

Recurring meetings and appointments have one master and one or more recurring instances. To cancel an entire series of a recurring meeting or appointment, you need to cancel the master meeting or appointment. Each recurring instance has a GetRecurringMaster method that returns its master meeting or appointment.

To cancel a single instance of a recurring meeting or appointment, open the instance and cancel it. You cancel single instances the same way you cancel a single meeting or appointment; see Canceling an Appointment or Canceling a Meeting.

To cancel a recurring meeting or appointment

  1. Open the calendar folder by using an Microsoft® ActiveX® Data Objects (ADO) database (ADODB) record set. Specify start and end times in the query so that instances are expanded in the calendar folder; see Calendar Folder Query.
  2. Locate any instance of the recurring meeting or appointment that you want to cancel, and then open it using an Appointment object.
  3. Open the master appointment using the IAppointment.GetRecurringMaster method. Verify that you are the organizer. Be sure to open the appointment or meeting in read/write mode by using adModeReadWrite.
  4. Set the configuration, and then create a Calendar Message object using the IAppointment.Cancel method.
  5. Add text to the Calendar Message object, if you want.
  6. Send the Calendar Message object by using the IMessage.Send method.
  7. Delete the master appointment or meeting from the calendar folder (optional).

    Note After you delete the master appointment or meeting for an instance, do not try to delete the master again for another instance of the same master.

The code in the following example gets meetings in the specified date range with the subject "Documentation Review Meeting" from the calendar of a specific user. Then it gets the master meeting, verifies that the user is the organizer, and finally cancels all instances of the recurring meeting.

Visual Basic

' Reference to Microsoft ActiveX Data Objects 2.5 Library
' Reference to Microsoft CDO for Exchange 2000 Library

Sub CancelRecurringAppointment(iAppt As CDO.Appointment, iMbx As IMailbox)

    Dim Rec         As New ADODB.Record
    Dim Rec2        As New ADODB.Record
    Dim iAppt       As New CDO.Appointment
    Dim iAppt2      As CDO.Appointment
    Dim iAtnds      As CDO.IAttendees
    Dim Config      As New CDO.Configuration
    Dim iCalMsg     As CDO.CalendarMessage
    Dim Address     As String
    Dim Index       As Integer
    Dim iPer        As CDO.Person

    Set iPer = iMbx

    'Set the configuration fields
    Config.Fields(cdoSendEmailAddress) = Username & "@" & DomainName
    Config.Fields.Update
    Set iAppt.Configuration = Config

    'Set the address of the user for comparing with the attendee value
    Address = "MAILTO:" & Username & "@" & DomainName

    'Open the record set for the items in the calendar folder
    Rec.Open CalendarURL
    Set Rs.ActiveConnection = Rec.ActiveConnection
    Rs.Source = "SELECT ""DAV:href"", " & _
                      " ""urn:schemas:httpmail:subject"", " & _
                      " ""urn:schemas:calendar:dtstart"", " & _
                      " ""urn:schemas:calendar:dtend"" " & _
                "FROM scope('shallow traversal of """ & CalendarURL & """') " & _
                "WHERE (""urn:schemas:calendar:dtstart"" >= CAST(""1999-10-01T08:00:00Z"" as 'dateTime')) " & _
                "AND (""urn:schemas:calendar:dtend"" <= CAST(""1999-11-01T08:00:00Z"" as 'dateTime'))" & _
                "AND (""urn:schemas:httpmail:subject"" = 'Documentation Review Meeting')"
    Rs.Open

    'Enumerate the record set
    Rs.MoveFirst
    Do Until Rs.EOF
      itemURL = Rs.Fields(CdoDAV.cdoHref).Value
      iAppt.DataSource.Open itemURL, , adModeReadWrite
      Set iAtnds = iAppt.Attendees
      For Index = 1 To iAtnds.Count
      'Check if this user is the organizer
      If iAtnds.Item(Index).IsOrganizer And iAtnds.Item(Index).Address = Address Then
        'This user is the organizer
        Set iAppt2 = iAppt.GetRecurringMaster(CalendarURL) 'Get the master
                                              'If already master, returns itself
        'Create a cancelation message
        iAppt2.Configuration = Config
        Set iCalMsg = iAppt2.Cancel
        iCalMsg.Message.TextBody = "This meeting is canceled."
        iCalMsg.Message.Send

        'Delete the master from the calendar folder (optional)
        itemURL = iAppt2.Fields(CdoDAV.cdoHref)
        Rec2.Open itemURL, , adModeReadWrite
        Rec2.DeleteRecord

        Exit Do 'Stop processing meeting instances
      End If
      Next Index

    Rs.MoveNext
    Loop

End Sub

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Declining a Previously Accepted Meeting

Attendees who want to remove themselves from a meeting can open the meeting in their calendar folder and send a decline response message to the organizer. The meeting remains in the attendees’ calendar with a status of Declined, unless the attendees delete the meeting from their calendar folders.

If you want to remove the meeting from your calendar without notifying the organizer, delete the meeting as shown in Canceling an Appointment.

Note It is a good idea to verify that you are not the organizer of a meeting before trying to decline that meeting.

The basic procedure for declining a previously accepted meeting is as follows:

  1. Open the calendar folder by using an Microsoft® ActiveX® Data Objects (ADO) database (ADODB) record set.
  2. Locate the meeting that you want to decline, and then open it using an Appointment object. Verify that you are not the organizer. Be sure to open the meeting in read/write mode by using adModeReadWrite.
  3. Create a Calendar Message object by using the IAppointment.Decline method.
  4. Add text to the Calendar Message object, if you want.
  5. Send the Calendar Message object by using the IMessage.Send method.
  6. Delete the declined meeting from the calendar folder (optional).

The code in the following example gets all of the meetings in the calendar of a specific user with the subject "Documentation Review Meeting." It verifies that the user is not the organizer, sends the Decline message, and then deletes the meeting from the calendar folder.

Visual Basic

' Reference to Microsoft ActiveX Data Objects 2.5 Library
' Reference to Microsoft CDO for Exchange 2000 Library

Sub DeclineAcceptedMeeting(iAppt As CDO.Appointment, iMbx As IMailbox)

    Dim Conn        As New Connection
    Dim Config      As New Configuration
    Dim iCalMsg     As CDO.CalendarMessage
    Dim iPer        As CDO.Person
    Dim Rec         As New ADODB.Record

    Set iPer = iMbx
    Conn.Provider = "ExOLEDB.DataSource"
    Conn.Open iMbx.BaseFolder
    Config.Fields(cdoSendEmailAddress) = iPer.Email
    Config.Fields(CDO.cdoActiveConnection) = Conn
    Config.Fields.Update

    With iAppt
        .Configuration = Config
        Set iCalMsg = .Decline
    End With

    iCalMsg.Message.TextBody = "Sorry, I cannot attend this meeting."
    iCalMsg.Message.Send

    iAppt.DataSource.Save

    Rec.Open iAppt.DataSource.SourceURL, Conn, adModeReadWrite
    Set iAppt = Nothing
    Rec.DeleteRecord

End Sub

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Inviting Additional Attendees

Both organizers and attendees can invite additional attendees to a meeting. You can invite attendees to a meeting in your calendar folder, and you can also forward meeting requests from your inbox.

If an attendee invites another attendee, the organizer's attendee list is not automatically updated. Therefore, when the new attendee responds to the meeting request, the organizer can choose to add the new attendee by processing the response message and saving the updated meeting. A meeting organizer should be able to process responses from attendees the organizer did not invite.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Inviting Attendees to a Meeting in the Calendar Folder

You can invite additional attendees to a meeting that already exists in your calendar folder. The IAppointment.Invite method returns a Calendar Message object that you send to the attendees being added.

For information on how to forward a meeting request from your inbox, see Forwarding a Meeting Request.

If the organizer of the meeting invites additional attendees, the meeting in the organizer's calendar folder is updated with the new attendees’ names. If an attendee invites additional attendees, the attendee list is not updated in the attendees’ or organizer's calendars. When the new attendees respond to the meeting request, the organizer can choose whether or not to add them to the attendee list.

Because a new meeting request is not automatically sent to existing attendees, their calendars are not updated with the new attendee names.

The basic procedure for inviting attendees to a meeting in the calendar folder is as follows:

  1. Open a meeting in the Calendar folder as shown in Getting Appointments and Meetings from Folders in Exchange. Be sure to open the appointment in read/write mode by using adModeReadWrite.
  2. Create a Calendar Message object.
  3. Call the IAppointment.Invite method, and then pass the list of attendees to invite by using the Calendar Message object.
  4. Call the ICalendarMessage.Message.Send method to send the message.
  5. Save the updated meeting.

The code in the following example opens a meeting in the calendar folder of a specific user, forwards the meeting to two new attendees, and then saves the updated meeting. In this example, the meeting is selected based on subject.

Visual Basic

' Reference to Microsoft ActiveX Data Objects 2.5 Library
' Reference to Microsoft CDO for Exchange 2000 Library

Sub InviteOthers(iAppt As CDO.Appointment, iMbx As IMailbox, NewList As String)

    Dim Conn As New ADODB.Connection
    Conn.Provider = "ExOLEDB.DataSource"
    Conn.Open iMbx.BaseFolder

    Dim Config As New CDO.Configuration
    'Set the configuration fields
    Config.Fields(cdoActiveConnection) = Conn
    Config(cdoMailboxURL) = iMbx.BaseFolder
    Config.Fields.Update

    iAppt.Configuration = Config
    Set iCalMsg = iAppt.Invite(NewList)

    iCalMsg.Message.Send

    'Save the meeting
    iAppt.DataSource.Save

End Sub

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Forwarding a Meeting Request

Forwarding a meeting request is similar to forwarding any message. If an attendee forwards a meeting request to someone else and that person responds to the meeting request, the response is sent to the meeting organizer.

For information on how to invite new attendees to a meeting that is already saved to your calendar, see Inviting Attendees to a Meeting in the Calendar Folder.

The basic procedure for forwarding a meeting request is as follows:

  1. Open the meeting request in your inbox by using a Calendar Message object, as shown in Processing a Calendar Message.
  2. Create a new Message object from the Calendar Message object by using the IMessage.Forward method.
  3. Address the new message, and then add any text you want.
  4. Call the IMessage.Send method to send the new message.

The code in the following example gets calendar messages with the subject "Documentation Review Meeting" from the inbox of a specific user. If the calendar message is a meeting request, it is automatically forwarded to the other users.

Visual Basic

' Reference to Microsoft ActiveX Data Objects 2.5 Library
' Reference to Microsoft CDO for Exchange 2000 Library

Sub ForwardRequest(iCalMsg As CDO.CalendarMessage, iMbx As IMailbox, EmailAddrs As String, strComment As String)

    Dim iCalPart As CDO.ICalendarPart
    Dim iMsg As CDO.Message
    Dim Conn As New ADODB.Connection
    Conn.Provider = "ExOLEDB.DataSource"
    Conn.Open iMbx.BaseFolder

    Dim Config As New CDO.Configuration
    Config(cdoActiveConnection).Value = Conn
    Config(cdoMailboxURL) = iMbx.BaseFolder
    Config.Fields.Update

    ' Make sure the message is a request.
    For Each iCalPart In iCalMsg.CalendarParts
        If iCalPart.CalendarMethod = "REQUEST" Then
            Set iMsg = iCalMsg.Message.Forward
            Set iMsg.Configuration = Config
            iMsg.To = EmailAddrs
            iMsg.TextBody = strComment
            iMsg.Send
            Exit For
        End If
    Next

End Sub

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Configuring the Appointment Object

The CDO Configuration object contains the configuration information needed by other CDO objects and methods. The http://schemas.microsoft.com/cdo/configuration namespace lists the fields defined for the Configuration object.

The sendemailaddress field is required for sending meeting requests and responses. This field should be set to the e-mail address of the user.

You can set other configuration fields, such as the sendusing field, if you need to. If your program creates multiple appointments or messages, you should create a single configuration object and reuse it for each appointment or message. This reduces the overhead involved in creating a new configuration object each time you create a new Appointment or Message object.

The code in the following example demonstrates how to set the configuration object for user12 in the exchange.microsoft.com domain. This example uses the default private store name "MBX."

Visual Basic

Dim Config As New CDO.Configuration
CalendarURL = "file://./backofficestorage/exchange.microsoft.com/MBX/user12/calendar/"

'Set the configuration for calendar messages
Config.Fields(cdoSendEmailAddress) = "user12@exchange.microsoft.com"
Config.Fields("CalendarLocation") = CalendarURL
Config.Fields.Update

CDO automatically gets some configuration information from the computer on which it is running. The information from the computer includes how messages are sent. To control how meeting requests and responses are sent, set the http://schemas.microsoft.com/cdo/configuration/sendusing field.

Related Topics

  • Configuration CoClass

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Example Code

This section contains code samples in Microsoft® Visual Basic® Scripting Edition (VBScript), Visual Basic, and Microsoft® Visual C++® that illustrate how to render a calendar to a Web page, view a calendar, and create an appointment.

Rendering a Calendar to a Web Page with ADO

Rendering Free-Busy Status to a Web Page with CDOEX

Viewing the Calendar Using ADO

Filtering and Viewing Calendars Using CDOEX and ADO

Creating an Appointment with CDOEX (Visual Basic)

Creating an Appointment with CDOEX (Visual C++)

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Rendering a Calendar to a Web Page with ADO

VBScript

Note The following example uses a file URL with the Exchange OLE DB (ExOLEDB) provider. The ExOLEDB provider also supports the HTTP URL scheme. Using the HTTP URL scheme allows both client and server applications to use a single URL scheme.
'Render calendar to a web page with ADO
'This sample renders a calendar to a web page using ADO
-->

<!--
'Build Instructions:
'1) Create a folder named "test" under inetpub/wwwroot.
'2) Save the following file in that folder with the mentioned name.
'3) Make the changes to the above file i.e. Change the calendarURL variable to reflect your mailbox and domain.
'4) Save the file.
'5) Open internet service manager and browse to the "test" folder.
'6) Right-click and go to properties.
'7) Go to the "Directory Security" tab.
'8) Click on "Edit" button next to the "handshake" icon.
'9) Uncheck "Anonymous Access".
'10) Check the "Basic authentication", "Digest authentication", and "Integrated Windows authentication".
'11) Click ok.
'12) Click ok.
'13) Load the asp in the browser.
-->

<%@ Language=VBScript%>
<%
    Dim CalendarURL
    Dim Rs
    Dim Rec
    Dim strSubject
    Dim strStartTime
    Dim strEndTime
   Dim strLocation

    Set Rs = CreateObject("ADODB.RecordSet")
    Set Rec = CreateObject("ADODB.Record")

    CalendarURL = "file://./backofficestorage/somedomain.microsoft.com/MBX/user1/calendar/"

    Rec.Open CalendarURL

    Set Rs.ActiveConnection = Rec.ActiveConnection
    Rs.Source = "SELECT ""DAV:href"", " & _
                " ""urn:schemas:httpmail:subject"", " & _
                " ""urn:schemas:calendar:dtstart"", " & _
                " ""urn:schemas:calendar:dtend"", " & _
                " ""urn:schemas:calendar:location"" " & _
                "FROM scope('shallow traversal of """ & CalendarURL & """') " & _
                "WHERE (""urn:schemas:calendar:dtstart"" >=CAST(""2000-01-01T08:00:00Z"" as 'dateTime')) " & _
                "AND (""urn:schemas:calendar:dtend"" <=CAST(""2000-01-31T08:00:00Z"" as 'dateTime'))"

    Rs.Open
    Rs.MoveFirst
    Response.Write "<TABLE border=1>"
    Response.Write "<TR><TD>Subject</TD><TD>Start Time</TD><TD>End Time</TD><TD>Location</TD></TR>"
    Do Until Rs.EOF
        strSubject = Rs.Fields("urn:schemas:httpmail:subject").Value
        strStartTime = Rs.Fields("urn:schemas:calendar:dtstart").Value
        strEndTime = Rs.Fields("urn:schemas:calendar:dtend").Value
        strLocation = Rs.Fields("urn:schemas:calendar:location").Value

        response.write "<TR><TD>" & strSubject & "</TD><TD>" & strStartTime & "</TD><TD>" & strEndTime & "</TD><TD>" & strLocation & "</TD></TR>"
        Rs.MoveNext
    Loop
    Response.Write "</TABLE>"
    Set Rs = Nothing
    Set Rec = Nothing
%>
<!--

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Rendering Free-Busy Status to a Web Page with CDOEX

VBScript

'Rendering free-busy status to a web page with CDOEx
-->
<!--
'Build Instructions:
'1) Create a folder named "test" under inetpub/wwwroot.
'2) Save the following file in that folder with the mentioned name.
'3)  Make the changes to the above file i.e. Change the UserName, DomainName, ServerName, strStartTime, strEndTime, iInterval variable to reflect your mailbox, domain and search criteria.
'4) Save the file.
'5) open internet service manager and browse to the "test"  folder
'6) right click and go to properties
'7) go to the "Directory Security" tab.
'8) Click on "Edit" button next to the "handshake" icon
'9) Uncheck "Anonymous Access"
'10) Uncheck "Anonymous access",  check the "Basic authentication", "Digest authentication", "Integrated Windows authentication"
'11) click ok
'12) click ok
'13) Load the asp in the browser.
-->

<%@ Language=VBscript%>
<%
    Sub PrintStatus(strStatus)
   Select Case strStatus
   Case "0"   'Free
      Response.Write "<TD>Free</TD></TR>"
   Case "1"   'Tentative
      Response.Write "<TD>Tentative</TD></TR>"
   Case "2"   'Busy
      Response.Write "<TD>Busy</TD></TR>"
   Case "3"   'Out Of Office

      Response.Write "<TD>Out Of Office</TD></TR>"
   End Select
    End Sub

    UserName = "Administrator"
    DomainName = "platinum-sdk.extest.microsoft.com"
    ServerName = "plt-test"
    strStartTime = #1/20/2000 7:00:00 AM#
    strEndTime = #1/20/2000 11:00:00 AM#
    iInterval = 30

    Set iAddr = createobject("CDO.Addressee")
    iAddr.EmailAddress = UserName & "@" & DomainName
    iAddr.CheckName ("LDAP://" & ServerName)

    strFreebusy = iAddr.GetFreeBusy(strStartTime, strEndTime, iInterval)

    Response.Write "<Table Border =1>"
    For i = 1 To Len(strFreebusy)
   If i = 1 Then
      Response.Write "<TR><TD>Start Time</TD><TD>" & strStartTime & " ~ </TD>"
   Elseif i = len(strFreebusy) Then
      Response.Write "<TR><TD>End Time</TD><TD>" & strEndTime & " ~ </TD>"
   Else
      Response.Write "<TR><TD>.</TD><TD> + " & iInterval & " min ~ </TD>"
   End If
   Call PrintStatus(Mid(strFreebusy, i, 1))
    Next
    Response.Write "</TABLE>"
    Set iAddr = Nothing
%>
<!--

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Viewing the Calendar Using ADO

VBScript

Note The following example uses a file URL with the Exchange OLE DB (ExOLEDB) provider. The ExOLEDB provider also supports the HTTP URL scheme. Using the HTTP URL scheme allows both client and server applications to use a single URL scheme.
'Viewing the Calendar using ADO
-->

<!--
'Steps to test this sample.

'1) Create a folder named "test" under inetpub/wwwroot.
'2) Save the above file in that folder with the mantioned name.
'3) Make the changes to the above file i.e. Change the strLocalPath  and DomainName variables to reflect your mailbox and domain.
'4) Save the file.
'5) open internet service manager and browse to the "test"  folder
'6) right click and go to properties
'7) go to the "Directory Security" tab.
'8) Click on "Edit" button next to the "handshake" icon
'9) Uncheck "Anonymous Access"
'10) check the "Digest Authentication" and "Integrated windows authentication" boxes
'11) click ok
'12) click ok
'13) Load the asp in the browser.
-->

<%@ Language=VBScript %>
<HTML>
<HEAD>
<META NAME="GENERATOR" Content="Microsoft Visual Studio 6.0">
<TITLE></TITLE>
</HEAD>
<BODY >

<%

'Viewing the Calendar using WebDAV.
'Set the required permissions on Exchange 2000 Server and IIS

Dim CalendarURL
Dim ItemURL
Dim Rs
Dim Rec
Dim Conn
Dim iAppt
Dim dateStartDate
Dim Subject
Dim DomainName
Dim strLocalPath

'specify your own domain
DomainName = "nrnobledom2.extest.microsoft.com"
'specify a URL to folder or item
strLocalPath = "MBX/User1/Calendar"

Set Rec = CreateObject("ADODB.Record")
Set Rs = CreateObject("ADODB.Recordset")

strURL = "file://./backofficestorage/" & DomainName & "/" & strLocalPath
Rec.Open strURL
Set Rs.ActiveConnection = Rec.ActiveConnection

Rs.Source = "SELECT ""DAV:href"", " & _
" ""urn:schemas:httpmail:subject"", " & _
" ""urn:schemas:calendar:dtstart"", " & _
" ""urn:schemas:calendar:dtend"" " & _
"FROM scope('shallow traversal of """ & strURL & """') "
Rs.Open
Rs.MoveFirst

%> <FONT FACE=ARIAL SIZE=2>
<br><br>
<TABLE cellspacing=0 cellpadding=4>
<tr><td>Subject:</td><td>Start:</td><td>end:</td></tr>
<%

Do Until Rs.EOF
response.write "<tr><td>"

Response.Write Rs.Fields("urn:schemas:httpmail:subject").Value
response.write "</td><td>"

Response.Write Rs.Fields("urn:schemas:calendar:dtstart").Value
response.write "</td><td>"

Response.Write Rs.Fields("urn:schemas:calendar:dtend").Value
response.write "</td><td>"

Rs.MoveNext
Loop
%>
</tr>
</table>
</BODY>
</HTML>
<!--

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Filtering and Viewing Calendars Using CDOEX and ADO

Visual Basic

Note The following example uses a file URL with the Exchange OLE DB (ExOLEDB) provider. The ExOLEDB provider also supports the HTTP URL scheme. Using the HTTP URL scheme allows both client and server applications to use a single URL scheme.
'Filter and viewing calendars using CDOEx and ADO
'Sample Description (This will appear in the .chm. as is; subject to edit)
' The sample demonstates filtering and viewing the appointments from a Calendar folder using CDO, ADO
' and ADSI.
'
' It opens Calendar folder using an ADODB record. It filters the appointments
' to include the ones that match the following selection criteria:
'
' 1. the status of the Appointment is marked as Busy and
' 2. the appointment occurs in between 12.25.1999 - 8:00:00 AM and 12.29.1999 - 8:00:00 AM, and
' 3. the appointment is a single appointment (i.e. not part of a recurring appointment).
'
' At the end, the sample prints the subject, location and attendees of
' each appointment item matching the selection criteria.
'
' Visual Basic Project Reference
'  - Microsoft CDO For Exchange 2000 Library
'  - Microsoft ActiveX Data Objects 2.5 Library
'  - Active DS Type Library

Private Sub FilterAppointments(User1)
Dim CalendarURL As String
Dim ItemURL As String
Dim Rs As New ADODB.Recordset
Dim Rec As New ADODB.Record
Dim iAppt As New CDO.Appointment
Dim iAttendees As Object
Dim DebugStr As String
Dim DomainName As String
Dim info As New ADSystemInfo

'Get the domain name
DomainName = info.DomainDNSName

' Construct the URL that will be used to reach the specified Calendar folder.
' Note: You can view somebody else's calendar folder (or a public folder),
' as long as that user's mailbox (or the public folder) resides in the local machine and you have enough
' permissions to do it.

' If the Calendar folder is a Public Folder, the CalendarURL string will look like the following:
' CalendarURL = "file://./backofficestorage/" & DomainName & "/public folders/" & "NameOfTheCalendarFolder"

CalendarURL = "file://./backofficestorage/" & DomainName & "/MBX/" & User1 & "/calendar/"

'Open a record set for the items in the calendar folder
Rec.Open CalendarURL

Set Rs.ActiveConnection = Rec.ActiveConnection
Rs.Source = "SELECT ""DAV:href"", " & _
" ""urn:schemas:calendar:busystatus"", " & _
" ""urn:schemas:calendar:instancetype"", " & _
" ""urn:schemas:calendar:dtstart"", " & _
" ""urn:schemas:calendar:dtend"" " & _
"FROM scope('shallow traversal of """ & CalendarURL & """') " & _
"WHERE (""urn:schemas:calendar:dtstart"" >= CAST(""1999-12-25T08:00:00Z"" as 'dateTime')) " & _
"AND (""urn:schemas:calendar:dtend"" <= CAST(""1999-12-29T08:00:00Z"" as 'dateTime'))" & _
"AND (""urn:schemas:calendar:busystatus"" = 'Busy')" & _
"AND (""urn:schemas:calendar:instancetype"" = 0)"
Rs.Open
If Not (Rs.EOF) Then
Rs.MoveFirst
DebugStr = ""
'Enumerate the record set, printing some information about each item
Do Until Rs.EOF

'Find the absolute uniform resource locator (URL) of each item
ItemURL = Rs.Fields(CdoDAV.cdoHref).Value

'Open appointment using its URL
iAppt.DataSource.Open ItemURL

DebugStr = DebugStr & "Subject: " & iAppt.Subject & vbLf
DebugStr = DebugStr & "Start-End Time: " & iAppt.StartTime & " - " & iAppt.EndTime & vbLf
DebugStr = DebugStr & "Location: " & iAppt.Location & vbLf
DebugStr = DebugStr & "Attendees: "

'Find the attendees invited to each meeting
Set iAttendees = iAppt.Attendees
For i = 1 To iAttendees.Count
DebugStr = DebugStr & iAttendees(i).DisplayName & " "
Next
DebugStr = DebugStr & vbLf & vbLf
Rs.MoveNext
Loop
Debug.Print DebugStr
Else ' No Appointments found matching the search criteria
Debug.Print "No Appointments found."
End If
End Sub

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Creating an Appointment with CDOEX

Visual Basic

Note The following example uses a file URL with the Exchange OLE DB (ExOLEDB) provider. The ExOLEDB provider also supports the HTTP URL scheme. Using the HTTP URL scheme allows both client and server applications to use a single URL scheme.
'Creating an appointment with CDOEx
Private Sub AddAppointment()
    Dim strDomainName As String
    Dim strLocalPath  As String
    Dim strContainerURL As String

    Dim iAppointment As New CDO.Appointment

    'create container URL
    strDomainName = "user1.kapokdom.microsoft.com"
    strLocalPath = "MBX/user1/Calendar"
    strContainerURL = "file://./BackOfficeStorage/" & strDomainName & "/" & strLocalPath

    'set appointment properties and save
    With iAppointment
        .Subject = "CDO For Exchange Programming Discussion"
        .Location = "Kapokdom"
        .TextBody = "We will discuss CDO for Exchange 2000 programming"
        .StartTime = "12/25/1999 11:00 AM"
        .EndTime = "12/26/1999 11:00 AM"
        .DataSource.SaveToContainer (strContainerURL)
    End With

    Set iAppointment = Nothing
End Sub

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Creating an Appointment with CDOEX

Visual C++

Note The following example uses a file URL with the Exchange OLE DB (ExOLEDB) provider. The ExOLEDB provider also supports the HTTP URL scheme. Using the HTTP URL scheme allows both client and server applications to use a single URL scheme.
//Creating an appointment with CDOEx

#import <cdoex.dll> rename_namespace("CDO") raw_interfaces_only

#include <stdio.h>
#include <tchar.h>

enum ConnectModeEnum
{
    adModeUnknown = 0,
    adModeRead = 1,
    adModeWrite = 2,
    adModeReadWrite = 3,
    adModeShareDenyRead = 4,
    adModeShareDenyWrite = 8,
    adModeShareExclusive = 12,
    adModeShareDenyNone = 16,
    adModeRecursive = 4194304
};

enum RecordCreateOptionsEnum
{
    adCreateCollection = 8192,
    adCreateStructDoc = -2147483648,
    adCreateNonCollection = 0,
    adOpenIfExists = 33554432,
    adCreateOverwrite = 67108864,
    adFailIfNotExists = -1
};

enum RecordOpenOptionsEnum
{
    adOpenRecordUnspecified = -1,
    adOpenSource = 8388608,
    adOpenAsync = 4096,
    adDelayFetchStream = 16384,
    adDelayFetchFields = 32768
};

void dump_com_error(_com_error &e)
{
    _tprintf(_T("Oops - hit an error!\n"));
    _tprintf(_T("\a\tCode = %08lx\n"), e.Error());
    _tprintf(_T("\a\tCode meaning = %s\n"), e.ErrorMessage());
    _bstr_t bstrSource(e.Source());
    _bstr_t bstrDescription(e.Description());
    _tprintf(_T("\a\tSource = %s\n"), (LPCTSTR) bstrSource);
    _tprintf(_T("\a\tDescription = %s\n"), (LPCTSTR) bstrDescription);
}

struct StartOle {
    StartOle() { CoInitialize(NULL); }
    ~StartOle() { CoUninitialize(); }
} _inst_StartOle;

void main(int argc, char** argv)
{
   HRESULT hr = S_OK;

   if(argc != 2)
   {
         printf("Usage: CreateAppt\r\n");
         printf("Example: CreateAppt \"file://./backofficestorage/MangoDomain.extest.microsoft.com/MBX/User1/calendar\"\n");
        exit(0);
   }

   wchar_t* folderURL = NULL;
   size_t size;
   size = mbstowcs(NULL,argv[1],0);
   folderURL = (wchar_t*)malloc(size * sizeof(wchar_t*) + 1);
   mbstowcs(folderURL,argv[1],size+1);

   BSTR bstrFolderURL = SysAllocString(folderURL);

   try
   {

      CDO::IAppointmentPtr pAppt(_uuidof(CDO::Appointment));
      CDO::IDataSourcePtr pDsrc;

      SYSTEMTIME st = {0};
      SYSTEMTIME et = {0};
      DATE dst, det;

      st.wYear = 1999;
      st.wMonth = 12;
      st.wDay = 21;
      st.wHour = 15;
      st.wMinute = 30;

      et.wYear = 1999;
      et.wMonth = 12;
      et.wDay = 21;
      et.wHour = 16;
      et.wMinute = 30;

      // Convert System value to double DATE
      SystemTimeToVariantTime(&st, &dst);
      SystemTimeToVariantTime(&et, &det);

      // Set Appointment's properties
      pAppt->put_Subject(L"CDO_VC:Important Appointment");
      pAppt->put_Location(L"Conference Room");
      pAppt->put_TextBody(L"Be there on time");
      pAppt->put_StartTime(dst);
      pAppt->put_EndTime(det);
      pAppt->get_DataSource(&pDsrc);

      // Save appointment
      hr = pDsrc->SaveToContainer(bstrFolderURL,
                        0,
                        (enum CDO::ConnectModeEnum) adModeReadWrite,
                        (enum CDO::RecordCreateOptionsEnum)adCreateOverwrite,
                        (enum CDO::RecordOpenOptionsEnum)adOpenSource,
                        L"",
                        L"");
      if (SUCCEEDED(hr))
         _tprintf(_T("Appointment created\n"));

   }
   catch(_com_error &e)
   {
      dump_com_error(e);
   }

   SysFreeString(bstrFolderURL);
}

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Managing Exchange 2000 Server Programmatically

The topics in this section describe how to manage Microsoft® Exchange 2000 Server programmatically.

Introduction

Before You Start

Concepts and Architecture

Programming Tasks

Example Code

Related Topics

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Introduction

This section contains introductory topics about Managing the Exchange 2000 Server Programmatically.

Server and Recipient Management

Overview

CDO for Exchange Management

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Server and Recipient Management

CDO for Exchange Management (CDOEXM) is a collection of Component Object Model (COM) classes and interfaces aggregated into Collaboration Data Objects (CDO) and Active Directory™ Service Interfaces (ADSI) classes. You can use CDOEXM to manage Microsoft® Exchange servers, mailbox stores, public stores, public folder trees, storage groups, and Exchange recipients (users, contacts, and groups) programmatically. You can use CDOEXM objects on your server. On computers where the Exchange Management components are installed, you can manage Exchange remotely. You can use CDO to work with items in the stores.

CDOEXM encapsulates and simplifies many programmatic tasks that are specific to managing Exchange 2000 Server. CDOEXM is useful for system administrators, who need to perform tasks such as managing the server remotely. You can also use CDOEXM to perform server-side Internet application tasks, such as automatically creating and registering users, managing data in public MDBs, and managing e-mail.

The following topics cover overview information about server and recipient management:

Overview

DLLs and Installation

Web Storage System Configuration

Active Directory and CDOEXM

Exchange Management Security

Web-Based Management

The following topics cover the CDOEXM classes and aggregated interfaces:

Managing Exchange Server

Managing Mail Recipients

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Overview

You can use CDO for Exchange Management (CDOEXM) Component Object Model (COM) classes to manage Microsoft® Exchange 2000 Server and its databases. Interfaces aggregated into CDO and Active Directory™ Service Interfaces (ADSI) classes allow you to manage recipients and their mailboxes. CDOEXM can be used either on the same computer as Exchange 2000 Server or remotely on computers that have the Exchange Management components installed.

For information about management classes, see Managing Exchange Server.

For information about aggregated interfaces, see Managing Mail Recipients.

Typical Uses

CDOEXM allows you to develop applications such as the following:

Business Critical Applications

Business applications can use the management tools to manage Web Storage System information and recipients programmatically, according to business logic or business rules.

System Administration

System administrators can build custom programs to move mailboxes between MDBs, mount public stores, create and enable recipients, move mailboxes, change forwarding addresses, and so on. You can build these programs quickly by using the recipient management interfaces.

MMC Snap-ins

CDOEXM is intended for use in developing your own MMC snap-ins for Exchange.

Remote Management

You can use CDOEXM to develop server-side objects to manage Exchange 2000 Server. These management objects can be invoked remotely by using Active Server Pages (ASP) pages.

Automated Services

Automatic services (or tools) can use CDOEXM. An example is a tool that uses CDOEXM to service Web-based clients, allowing them to register as new users in a Web Storage System, granting them access to public stores, and giving them mailboxes.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


CDO for Exchange Management

CDO for Exchange Management (CDOEXM) is a collection of Component Object Model (COM) classes and interfaces aggregated into Collaboration Data Objects (CDO) and Active Directory™ Service Interfaces (ADSI) classes. You can use CDOEXM to manage Microsoft® Exchange servers, mailbox stores, public stores, public folder trees, storage groups, and Exchange recipients (users, contacts, and groups) programmatically. You can use CDOEXM objects on your server. On computers where the Exchange Management components are installed, you can manage Exchange remotely. You can use CDO to work with items in the stores.

CDOEXM is useful for system administrators who need to do such things as manage the server remotely. You can also use CDOEXM for server applications typically used in Internet applications, such as automatic registration of users and e-mail management. CDOEXM encapsulates and simplifies many programmatic tasks that are specific to managing Exchange 2000 Server.

This topic describes the objects and interfaces in CDOEXM. It also covers CDOEXM security issues, scripting, remote management, and lists required DLLs.

For a complete description of CDOEXM, see Server and Recipient Management.

In this section, you will find the following topics, which cover overview information about managing the store:

Active Directory and CDOEXM

DLLs and Installation

Exchange Management Security

Web Based Management

In addition, you will find the following topics, which cover the CDOEXM objects and aggregated interfaces:

Managing Exchange Server

Managing Mail Recipients

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Before You Start

The topics in this section provide information you should know before you start Managing Exchange 2000 Server Programmatically.

DLLs and Installation

CDOEXM and ADSI

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


DLLs and Installation

The following table shows the dynamic-link library (DLL) that contains the CDO for Exchange Management (CDOEXM) classes and aggregated interfaces.

DLL Name | Description
CDOEXM.DLL | Collaboration Data Objects for Exchange Management (CDOEXM)

Installation of CDOEXM

When you install Microsoft® Exchange, CDOEXM is automatically installed with the Exchange Management Components. If you install Exchange Management User Interface, the Management Components are also installed.

To use CDOEXM on a remote computer, the Exchange Management Components must be installed on the remote computer.

Dependent DLLs

CDOEXM can use the following DLLs:

ACTIVEDS.DLL

ADVAPI32.DLL

CLUSAPI.DLL

COMCTL32.DLL

EXCHMEM.DLL

KERNEL32.DLL

MSVCP50.DLL

MSVCRT.DLL

NETAPI32.DLL

OLE32.DLL

OLEAUT32.DLL

RESUTILS.DLL

RPCRT4.DLL

SECURITY.DLL

USER32.DLL

VERSION.DLL

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


CDOEXM and ADSI

CDO for Exchange Management (CDOEXM) and Active Directory™ Service Interfaces (ADSI) objects work well together. The following is a list of some of the things you can do using ADSI and CDOEXM:

  • Use CDOEXM to create new users and their associated Microsoft® Exchange 2000 Server mailboxes.
  • Manage user and contact information in Microsoft® Active Directory™ by using the same objects and logic.
  • Manage Public Folder tree information and related information in Active Directory, when you use the CDOEXM component.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Concepts and Architecture

The topics in this section describe general programming principles for managing Microsoft® Exchange 2000 Server.

Web Storage System Configuration

Active Directory and CDOEXM

Web-Based Management

Exchange Management Security

Managing Exchange Server

Managing Mail Recipients

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Web Storage System Configuration

The Web Storage System saves information in storage groups. Storage groups can contain public stores and mailbox stores. Stores are sometimes referred to as message databases (MDBs), a name taken from their file extension.

In Microsoft® Exchange, administrators use CDO for Exchange Management (CDOEXM) to manage storage groups, in which they create public and mailbox stores. Administrators access and use storage groups; storage groups do not provide any representation to users or applications that access the Web Storage System.

Users and applications see Web Storage System data as paths that can be accessed by using World Wide Web Distributed Authoring and Versioning (WebDAV) paths or file://./ paths. Data in public stores is presented in the Web Storage System, in folder trees. To access data in the public stores, you use paths of the folder tree. To access data in a mailbox store, you use paths to mailboxes and subfolders in the mailboxes.

For a more sequential look at configuring an Exchange store, see Setting Up a Store.

As you configure your public and mailbox stores, you can view your current server configuration by using the Exchange System Manager MMC snap-in. You may need to refresh the MMC display to see the current configuration.

Folder Trees

Folder trees organize public folder data in hierarchical folders for access by Web Storage System applications, Microsoft® Outlook®, and custom applications using Exchange 2000 Server. In Exchange 2000 Server a folder tree can be distributed across one or more MDBs.

Using folder trees, you can replicate information to public stores on other servers. For more information about replication, see Folder Tree Replication.

MDBs

All store data is kept in MDBs, which in Exchange 2000 Server are Microsoft Jet databases. With Exchange 2000 Server, however, a server can have more than one store. The MDBs can be placed on different servers to improve performance, availability, reliability, and to simplify MDB maintenance.

Read these topics for more information about configuring the Web Storage System:

Rules About Folder Trees and MDBs

Folder Tree Replication

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Rules about Folder Trees and MDBs

Logical constraints to using folder trees include:

  • Each public information store must be associated with one and only one folder tree.
  • A public store cannot be associated with the folder tree of another public store on the same server.
  • A public store can be associated with a folder tree of a public store on another server. For more information, see Folder Tree Replication.

The following diagram shows how these rules are applied in an incomplete folder tree and server configuration.

Public Store B must be associated with a folder tree, but it cannot be Folder Tree 1 (because Folder Tree 1 is already associated with a store on the server).

Folder Tree 2 cannot be associated with Public Store A (because Public Store A is already associated with a folder tree).

Public Store 2A can be associated with Folder Tree 1 (because it is on a remote server). Public Store 2A may be a replica of Public Store A, depending on the replication configuration and whether Public Store 2A contains data also stored in Public Store A.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Folder Tree Replication

You can replicate folder trees on multiple servers. Each server will have its own public information store, and the server will keep the information mirrored.

Note Replicating and configuring what is displayed in a folder tree is performed outside CDO for Exchange Management (CDOEXM). Use CDOEXM to configure the associations between the public stores and the folder trees.

For related information, see Setting Up a Store.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Active Directory and CDOEXM

Performing management with CDO for Exchange Management (CDOEXM) involves gathering and modifying information in Microsoft® Exchange 2000 Server and Microsoft® Active Directory™ in Microsoft® Windows® 2000. Active Directory information is configured in namespaces by using LDAP. It is important to understand the role of Active Directory for Exchange 2000 Server.

In CDOEXM classes, the IDataSource2 interface is provided for opening, managing, saving, and deleting Exchange-related Active Directory objects.

CDOEXM and ADSI

The Exchange 2000 Server data that resides in Active Directory can be accessed by using Active Directory™ Service Interfaces (ADSI). ADSI is a generic API, however, that has no specific functions for managing the Exchange data in Active Directory. Also, ADSI cannot access data in Exchange 2000 Server.

CDOEXM encapsulates and simplifies Exchange management tasks so that data in both Active Directory and Exchange are managed as needed.

For information about a class for obtaining and building Active Directory paths, see the ADSI Pathname section in the Platform SDK.

For more information about managing Exchange 2000 using Active Directory and CDOEXM, read the following topics:

Using CDOEXM with Non-Exchange Web Storage Systems

Building Active Directory Paths

Retrieving Folder Tree URLs

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Using CDOEXM with Non-Exchange Web Storage Systems

The CDO for Exchange Management (CDOEXM) objects included with Microsoft® Exchange 2000 Server Service Pack 1 or later support management of a Web Storage System based on Exchange and Web Storage System stores that are not Exchange-based.

Use the DataSource.Open method to obtain a URL for accessing the URL:

Visual Basic

    Dim objSv as new CDOEXM.ExchangeServer
    objSV.DataSource.Open("SERVERNAME")

If your applications use the CDOEXM.ExchangeServer object to manage Web Storage System servers, you can open the CDOEXM data source using the DNS name of the server in addition to a user interface (UI). When the Web Storage System is opened using the computer name, applications using CDOEXM can manage the server even if the Web Storage System is not Exchange-based.

When the DataSource.Open command completes, the contents of the SourceURL property will vary depending on the type of Web Storage System opened. Exchange servers use the LDAP:// protocol specifier in the URL, while non-Exchange-based servers use the file:// protocol specifier. The following table shows SourceURLs in the format returned by an Exchange-based Web Storage System and by a non-Exchange Web Storage System. Your application would see installation-specific values for SERVERNAME, OrganizationName, and UpperLevelDomain.

Web Storage System Type | DataSource.SourceURL
Exchange | LDAP://SERVERNAME/CN=SERVERNAME,CN=Servers,CN=First Administrative Group,CN=Administrative Groups,CN=First Organization,CN=Microsoft Exchange,CN=Services, CN=Configuration,DC=OrganizationName,DC=UpperLevelDomain
Non-Exchange | file://SERVERNAME/CN=SERVERNAME,CN=Servers

Server configuration data for both Web Storage System types can be accessed using the base URL returned in the SourceURL property, and your application does not need to know in advance what type of system it is accessing.

Because the different Web Storage System types use different protocol specifiers, your management applications should avoid changing the protocol, should avoid using hard-coded base URLs, and should avoid assuming that there is an unchanging container organization inside a Web Storage System. Instead, use Collaboration Data Objects (CDO) with Microsoft® ActiveX® Data Objects (ADO) and CDOEXM to navigate the stores, folders, and other objects.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Building Active Directory Paths

You can programmatically build Microsoft® Active Directory™ paths by using CDO for Exchange Management (CDOEXM) Component Object Model (COM) classes. The following example shows how you can use each CDOEXM object to enumerate storage groups, public and mailbox stores in the storage groups, and the folder trees in which the stores appear.

Visual Basic

Private Sub EnumerateStore()

  Dim iExs As New CDOEXM.ExchangeServer
  Dim isg As New CDOEXM.StorageGroup
  Dim ipsDB As New CDOEXM.PublicStoreDB
  Dim imbxDB As New CDOEXM.MailboxStoreDB
  Dim ift As New CDOEXM.FolderTree

  Dim ds2 As IDataSource2
  Set ds2 = iExs

  Debug.Print Chr(13) + Chr(13) + Chr(13) + "================================="

  Dim server_nm As String
  server_nm = Environ("COMPUTERNAME") 'The computer name is the servername.

  ds2.Open server_nm
  Debug.Print "ExchangeVersion = " + iExs.ExchangeVersion

  Debug.Print "DirectoryServer = " + iExs.DirectoryServer

  Dim storegroup As Variant
  Dim pubstore As Variant
  Dim mbx As Variant

  For Each storegroup In iExs.StorageGroups
    Debug.Print "StorageGroup Distinguished Name = " + storegroup + Chr(13)
    isg.DataSource.Open storegroup

    For Each pubstore In isg.PublicStoreDBs

      Debug.Print "Public Store   = " + pubstore
      ipsDB.DataSource.Open pubstore
      Debug.Print "        Name   = " + ipsDB.Name + Chr(13)

      Debug.Print "FolderTree     = " + ipsDB.FolderTree
      ift.DataSource.Open ipsDB.FolderTree
      Debug.Print " RootFolderURL = " + ift.RootFolderURL
      Debug.Print "          Name = " + ift.Name + Chr(13)

    Next 'public store
    For Each mbx In isg.MailboxStoreDBs

      Debug.Print "Mailbox        = " + mbx
      imbxDB.DataSource.Open mbx
      Debug.Print "          Name = " + imbxDB.Name + Chr(13)

    Next 'mailbox
  Next 'storage group

  Set iExs = Nothing
  Set isg = Nothing
  Set ipsDB = Nothing
  Set imbxDB = Nothing
  Set ift = Nothing

End Sub

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Retrieving Folder Tree URLs

Folder tree URLs are required for various store management operations. The following code locates a folder tree by name on a given server. It returns the full URL, which you can use when creating a public store. The following example accesses the folder tree using ActiveX Data Objects (ADO).

Visual Basic

'//////////////////////////////////////////////////////////////////////////////////
'// Function:   GetFolderTreeURL
'// Purpose:    To get the Folder Tree Hierarchies URL
'// Input:      strComputerName = contains the name of the Exchange 2000 Server
'//             strFHName = contains the name of the Folder Tree Hierarchy to be found
'// Output:     Nothing
'//
'// Notes:      The function is useful for checking to see if this folder tree url
'//             is already in use.  Also it is useful when creating a new
'//             public or mailbox store (because they require a folder tree URL).
'//
'//////////////////////////////////////////////////////////////////////////////////

Public Sub GetFolderTreeURL(ByVal strComputerName As String, _
                                               ByRef strFHName As String)
    On Error Resume Next
    Dim RootDSE     As IADs
    Dim conf        As IADs

    Dim conn        As New ADODB.Connection
    Dim comm        As New ADODB.Command
    Dim rs          As ADODB.Recordset

    'Get the default IExchangeServer interface
    Dim iServer         As New CDOEXM.ExchangeServer

    Dim strPath         As String
    Dim strDSAdminName  As String
    Dim strDSAdminPass  As String
    Dim strDNFolder     As String

    strFHName = ""

    ' Bind to the Exchange Server
    iServer.DataSource.Open strComputerName

    Set RootDSE = GetObject("LDAP://" + iServer.DirectoryServer + "/RootDSE")
    strPath = "LDAP://" & iServer.DirectoryServer & "/" & RootDSE.Get("configurationNamingContext")

    ' Set the Provider for the connection object
    conn.Provider = "ADsDSOObject"

    'You will need to provide login credentials if you are not logged in
    'with an administrator security context.

    ' Open connection
    conn.Open

    ' Set command to connection object
    Set comm.ActiveConnection = conn

    comm.CommandText = "<" & strPath & ">" & ";(objectClass=msExchPFTree);ADsPath,distinguishedName,Name;subtree"

    ' Execute command
    Set rs = comm.Execute

    ' Get the Default FolderTreeHierarcy
    Do While Not (rs.EOF)
        'You can print access folder tree information here
        'Debug.Print rs.Fields("ADsPath").Value
        'Debug.Print rs.Fields("distinguishedName")
        'Debug.Print rs.Fields("Name")
        strDNFolder = rs.Fields("distinguishedName")
        'cut the folder name to get the Folder Hierarchies
        strFHName = Mid(strDNFolder, InStr(2, strDNFolder, "CN="))
        If strFHName <> "" Then
            Exit Do
        Else
            rs.MoveNext
        End If
    Loop
    ' test if the URL to the FolderTreeHierarcy is empty
    If strFHName = "" Then
        Debug.Print "No Folder Hierarchy Name Found."
    End If

    'Cleanup
    Set RootDSE = Nothing
    Set conf = Nothing

    Set conn = Nothing
    Set comm = Nothing
    Set rs = Nothing
    Set iServer = Nothing

End Sub

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Web-Based Management

Remote management over the Web can use server-side Active Server Pages (ASP) pages to run scripts that create CDO for Exchange Management (CDOEXM) objects to perform Microsoft® Exchange management tasks.

Scripts have security restrictions when they are run out of the administrator's process (such as from a server-side ASP file). For running scripts out of process, take one of the following two actions to have administrator rights:

  • Run the scripts within a Script Host that has administrator privileges.
  • Use the script to create objects that obtain administrator privileges. Then, perform the management tasks from within the objects.

For obtaining administrative privileges outside of an administrator's process, see Exchange Management Security.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Exchange Management Security

CDO for Exchange Management (CDOEXM) objects must be run in a security context that is sufficient to perform management tasks. This is also true for the CDO and Active Directory™ Service Interfaces (ADSI) objects with aggregated CDOEXM recipient interfaces. CDOEXM uses the Microsoft® Windows® 2000 security model for accessing Microsoft® Exchange 2000 Server. Authentication as a Windows 2000 user will give you the administrative rights associated with that user. The following are ways to obtain administrative privileges for CDOEXM objects:

Log On as an Administrator

As an administrator, you can create objects to perform system management.

Wrap the COM Classes using COM+

In many automated processes, you may want to allow users without administrative privileges to perform some specific Exchange management tasks (for example, allowing them to register at your Web site and gain access to public stores). You can set up a server-side Active Server Pages (ASP) page that can run management objects within their own security contexts.

To give your management objects security contexts, you can wrap them in COM+ applications (formerly called an MTS package). COM+ applications allow you to specify the identity, and thus the security context, of that object as a user with administrative rights. For more information, see "Security in COM+" in the COM+ section of the Platform SDK in the MSDN® Library.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Managing Exchange Server

CDO for Exchange Management (CDOEXM) provides five Component Object Model (COM) classes for managing Microsoft® Exchange 2000 Server and its MDBs. The CDOEXM object models are at CDO for Exchange Management Objects.

All CDOEXM interfaces are Automation compatible and thus can be used in Microsoft® Visual Basic® and scripting.

The classes and their uses are briefly described in this topic.

The Server COM Class

The ExchangeServer COM class is for managing the overall Exchange 2000 Server. The IExchangeServer interface on this class allows you to obtain information such as the name of the server, the type of the server, version of the server, and the storage groups that are on the server. You can also set server characteristics such as enabling or disabling message tracking, or setting the number of days before log files are removed.

The FolderTree COM Class

The FolderTree COM class is for creating, managing, and deleting folder trees. The IFolderTree interface allows you to manage the folder tree and the tree replicas.

For more information, see Web Storage System Configuration.

The StorageGroup COM Class

The StorageGroup COM class allows you to create, manage, and delete storage groups. When you create a store, you must place it in a storage group. The storage group management tasks include managing log files for the group and resetting the database for the stores. The IStorageGroup interface allows you to access the underlying Microsoft Jet database configuration information for your stores.

For more information, see Setting Up a Store.

The PublicStoreDB COM Class

The PublicStoreDB COM class is for managing public stores in Exchange 2000 Server. The IPublicStoreDB interface allows you to create, modify, and delete public stores.

Users of the Web Storage System access public stores through folder trees.

The MailboxStoreDB COM Class

The MailboxStoreDB COM class is for creating and deleting Exchange 2000 Server mailbox stores. Individual mailboxes are created in and managed from mailbox stores. The IMailboxStoreDB interface allows you to mount or dismount a mailbox store, or to access and set information pertaining to a mailbox store.

Related Topics

  • Setting Up a Store

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Setting Up a Store

This section discusses the sequence for creating public folders and mailboxes in Microsoft® Exchange 2000 Server with CDO for Exchange Management (CDOEXM) objects.

Create a Storage Group

A default storage group is created when Exchange 2000 Server is installed. When you create stores, you can use this default storage group or create a new storage group.

For a code sample of creating a storage group, see Creating a Storage Group.

Create a Folder Tree

You must create a folder tree before you create public stores, because it is necessary to identify an existing folder tree when you create a store.

Note You can also use the default folder tree that is created when Exchange 2000 Server is installed. However, you must strictly follow the rules governing relationships between folder trees and public stores.

For a code sample of creating a Folder Tree, see Creating a Folder Tree.

Create Public Stores

You can now create the public stores. When creating stores, you must specify a storage group in which the store is to be managed, and a folder tree to associate with the public store.

For public store code samples, see Creating a Public Store.

Create Mailbox Stores

You can now create the mailbox stores. When creating mailbox stores, you must specify both a storage group in which the store is to be managed, and a public store that will be associated with the mailbox store. Public folders and files for users that have mailboxes in the new mailbox store can be kept in the associated public store. Depending on the Exchange replication configuration, public folder data for those users might be stored in a public store different than the one originally associated with the new mailbox store.

For mailbox store code samples, see Creating a Mailbox Store.

Your store now looks like the following:

Create Public Folders and Mailboxes

You can now create public folders and mailboxes. You can also give users permissions to create public folders and create their own mailboxes.

For an example of how to create a folder, see Creating Folders.

For information about creating and managing mailboxes, including examples, see Managing Mail Recipients.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Managing Mail Recipients

This topic covers how mail recipients can be programmatically managed in Microsoft® Exchange 2000 Server. The management is provided by CDO for Exchange Management (CDOEXM) interfaces that are aggregated into CDO and Active Directory™ Service Interfaces (ADSI) objects capable of acting as recipients.

The CDOEXM recipient interfaces are used in conjunction with information in CDO and ADSI objects for tasks such as creating, moving, and deleting recipients. These interfaces also provide the means for setting mailbox properties such as limits, forwarding properties, proxy addresses, and alias names.

See the following subtopics for more information:

Recipient Management Interfaces

Using the Interfaces in Context

Recipients, Folders, and Groups

Accessing Mailboxes and Folders

E-mail Addresses Stored as Active Directory Paths

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Recipient Management Interfaces

The following table lists the CDO for Exchange Management (CDOEXM) interfaces and the CDO and Active Directory™ Service Interfaces (ADSI) objects into which they are aggregated.

Aggregated CDOEXM interface | CDO and ADSI COM classes
IMailRecipient | CDO.Person CDO.Folder ADSI Contact (IADS) ADSI Group (IADSGroup) ADSI User (IADSUser)
IMailboxStore | CDO.Person ADSI User (IADSUser)
IDistributionList | ADSI Group (IADSGroup)

The CDOEXM IMailRecipient interface is used to set whether a recipient is a mail-enabled object.

The CDOEXM IMailboxStore interface is used to create mailboxes for users, and to set other mailbox policies such as how long to keep deleted messages.

Related Topics

  • Creating a Mail-Enabled Recipient

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Using the Interfaces in Context

The CDO for Exchange Management (CDOEXM) recipient interfaces (IMailRecipient and IMailboxStore) are aggregated into existing CDO and Active Directory™ Service Interfaces (ADSI) classes.

For important information about accessing recipient mailboxes and folders by using ADSI or Exchange OLE DB (ExOLEDB), see Accessing Mailboxes and Folders.

The following example demonstrates the coordinated use of the CDO.Person interface (and its underlying object) with the IMailboxStore interface to create a mailbox-enabled recipient. The example uses the CreateUserURL function, which is described in the topic Creating a User URL.

Visual Basic

Sub CreateMailboxCDOPerson(strFirstName As String, _
                                   strLastName As String, _
                                   strHomeMDBUrl As String)
'strHomeMDBUrl should look like this
'strHomeMDBUrl = "CN=Mailbox Store (MYSTORE),CN=First Storage Group,
'                 CN=InformationStore,CN=MYSTORE,CN=Servers,
'                 CN=First Administrative Group,CN=Administrative Groups,
'                 CN=IASI,CN=Microsoft Exchange,CN=Services,CN=Configuration,
'                 DC=mydomain,DC=extest,DC=microsoft,DC=com"

    Dim oPerson         As New CDO.Person
    Dim oMailbox        As CDOEXM.IMailboxStore
    Dim strUserName     As String
    Dim strURL          As String
    Dim strContainerName As String

    strUserName = strFirstName & strLastName

    strContainerName = "Users"
    ' Create URL for the user
    CreateUserURL strURL, strContainerName, False, strUserName

    oPerson.FirstName = strFirstName
    oPerson.LastName = strLastName

    oPerson.DataSource.SaveTo strURL

    ' Create Mailbox
    Set oMailbox = oPerson
    oMailbox.CreateMailbox strHomeMDBUrl

    ' Save
    oPerson.DataSource.Save

    'CleanUp
    Set oPerson = Nothing
    Set oMailbox = Nothing

End Sub

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Recipients, Folders, and Groups

A recipient can be a person (user or contact), a folder, or a group. The following list defines the types of recipients with respect to their objects and mailbox types:

  • Mailbox-enabled recipients have both a mail address and a Microsoft® Exchange mailbox.
  • Mail-enabled recipients have a mail address but do not have an Exchange mailbox. Mail sent to this type of recipient is typically forwarded to another e-mail location outside of Exchange.
  • Mail-enabled folders are folders in which items can be posted.
  • Mail-enabled groups are distribution lists.

The following table defines the characteristics of these mail recipient types.

Recipient type | E-mail address | Actual location in store
Mailbox-enabled recipient | Address can be a store mailbox or be set to a forwarding address. | The recipient's mailbox.
Mail-enabled recipient | Mail is forwarded to this address. | None.
Mail-enabled folder | An address to the folder. | The public folder.
Mail-enabled group | A group address. (Mail is routed to those in the group.) | None. The group serves as a distribution list.

When any of these recipient types is disabled, Exchange 2000 Server does not provide access to them by standard e-mail protocols. From an e-mail perspective, the server does not recognize the address unless it is enabled.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Accessing Mailboxes and Folders

When managing recipients, the CDO for Exchange Management (CDOEXM) recipient interfaces access and modify items in both Microsoft® Active Directory™ and Microsoft® Exchange 2000 Server.

For more information about the use of Active Directory in Exchange, see Active Directory and CDOEXM.

Person and User Objects Use LDAP

Recipients are defined in both Active Directory and Exchange 2000 Server. The principal location to bind to a recipient is in Active Directory. Thus, the CDOEXM interfaces in the Person and User objects bind to Active Directory by using an LDAP URL. The following example illustrates this:

Dim objPerson As New CDO.Person
objPerson.DataSource.Open
"LDAP://MYSERVER1/CN=jamessmith,CN=users,
DC=CompanyADomain,DC=Dev,DC=com"

The LDAP URL consists of the following parts:

"LDAP://servername/CN=RecipientName,CN=container,CN=container2,CN=containerN,
DC=DomainNamePart,DC=DomainNamePart2,DC=DomainNamePartn"

For related information, see Building Active Directory Paths.

Folder Objects Use ExOLEDB

Note The following example uses a file URL with the Exchange OLE DB (ExOLEDB) provider. The ExOLEDB provider also supports the HTTP URL scheme. Using the HTTP URL scheme allows both client and server applications to use a single URL scheme.

To use CDOEXM interfaces in the Folder object, you connect directly to a store by using the ExOLEDB provider. Connect to the store by providing a "File://./" URL. An Open statement might look like the following:

Dim objFolder As New CDO.Folder
fullurl = "file://./backofficestorage/MyDomain.wherever.com/Public Folders/Folder3"
objFolder.DataSource.Open fullurl, , adModeReadWrite, adFailIfNotExists

The File URL parts are defined as follows:

 fullurl = "file://./backofficestorage/DomainName/FolderName"

For an example of working with a folder, see Building a Restricted Address List.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


E-mail Addresses Stored as Active Directory Paths

E-mail addresses are converted (stored) as Microsoft® Active Directory™ paths when specific CDO for Exchange Management (CDOEXM) interface properties are set. Some of these properties can receive recipients as e-mail addresses (such as IMailboxStore, ForwardTo, or Delegates).

For example, setting IMailboxStore.ForwardTo to user1@somewhere.microsoft.com results in the ForwardTo value being set to the Active Directory path (for example, cn=Private MDB,cn=First Storage Group,...).

To complete an LDAP URL by using an Active Directory path, you typically must add "LDAP://server/" and "CN=first tree item."

For more information about the use of Active Directory in Microsoft® Exchange, see Active Directory and CDOEXM.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Programming Tasks

This section does not currently contain any topics. Information will be provided here as it becomes available.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Example Code

The topics in this section contain example code that you can use to manage storage groups, stores, recipients, mailboxes, and folders in Microsoft® Exchange 2000 Server programmatically.

Server Management Tasks

Recipient Management Tasks

Management Tasks Using ADSI

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Server Management Tasks

The following tasks use CDO for Exchange Management (CDOEXM) objects to configure Microsoft® Exchange 2000 Server:

Enumerating Storage Groups and Stores

Retrieving Folder Tree URLs

Creating a Folder Tree

Deleting a Folder Tree

Creating a Storage Group

Deleting a Storage Group

Creating a Public Store

Deleting a Public Store

Creating a Mailbox Store

Deleting a Mailbox Store

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Enumerating Storage Groups and Stores

The following example shows how you can use each CDO for Exchange Management (CDOEXM) object to enumerate storage groups, public and private stores in the storage groups, and the folder trees in which the stores appear. Various parts of this sample can be useful for locating such objects in the Exchange 2000 server.

Visual Basic

' This subroutine will find all the Stores on the local machine.
Sub EnumerateStore()

  Dim iExs As New CDOEXM.ExchangeServer
  Dim isg As New CDOEXM.StorageGroup
  Dim ipsDB As New CDOEXM.PublicStoreDB
  Dim imbxDB As New CDOEXM.MailboxStoreDB
  Dim ift As New CDOEXM.FolderTree

  Dim ds2 As IDataSource2
  Set ds2 = iExs

  Debug.Print Chr(13) + Chr(13) + Chr(13) + "================================="

  Dim server_nm As String
  server_nm = Environ("COMPUTERNAME") 'The computer name is the servername.

  ds2.Open server_nm
  Debug.Print "ExchangeVersion = " + iExs.ExchangeVersion

  Debug.Print "DirectoryServer = " + iExs.DirectoryServer

  Dim storegroup As Variant
  Dim pubstore As Variant
  Dim mbx As Variant

  For Each storegroup In iExs.StorageGroups
    Debug.Print "StorageGroup Distinguished Name = " + storegroup + Chr(13)
    isg.DataSource.Open storegroup

    For Each pubstore In isg.PublicStoreDBs

      Debug.Print "Public Store   = " + pubstore
      ipsDB.DataSource.Open pubstore
      Debug.Print "        Name   = " + ipsDB.name + Chr(13)

      Debug.Print "FolderTree     = " + ipsDB.FolderTree
      ift.DataSource.Open ipsDB.FolderTree
      Debug.Print " RootFolderURL = " + ift.RootFolderURL
      Debug.Print "          Name = " + ift.name + Chr(13)

    Next 'public store
    For Each mbx In isg.MailboxStoreDBs

      Debug.Print "Mailbox        = " + mbx
      imbxDB.DataSource.Open mbx
      Debug.Print "          Name = " + imbxDB.name + Chr(13)

    Next 'mailbox
  Next 'storage group

  Set iExs = Nothing
  Set isg = Nothing
  Set ipsDB = Nothing
  Set imbxDB = Nothing
  Set ift = Nothing

End Sub

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Retrieving Folder Tree URLs

Folder tree URLs are required for various store management operations. The following code will locate a folder tree by name on an Exchange 2000 server. It will return the full URL, which you can use when creating a store.

Visual Basic

'//////////////////////////////////////////////////////////////////////////////////
'// Function:   GetFolderTreeURL
'// Purpose:    To get the Folder Tree Hierarchies URL
'// Input:      strComputerName = contains the name of the Exchange 2000 Server
'//             strFHName = containes the name of the Folder Tree Hierarchy to be found
'// Output:     Nothing
'//
'// Notes:      The function is useful for checking to see if this folder tree url
'//             is already in use.  Also it is useful when creating a new
'//             public or mailbox store (since they require a folder tree URL).
'//
'//////////////////////////////////////////////////////////////////////////////////

Public Sub GetFolderTreeURL(ByVal strComputerName As String, _
                                               ByRef strFHName As String)
    On Error Resume Next
    Dim RootDSE     As IADs
    Dim conf        As IADs

    Dim conn        As New ADODB.Connection
    Dim comm        As New ADODB.Command
    Dim rs          As ADODB.Recordset

    'Get the default IExchangeServer interface
    Dim iServer         As New CDOEXM.ExchangeServer

    Dim strPath         As String
    Dim strDSAdminName  As String
    Dim strDSAdminPass  As String
    Dim strDNFolder     As String

    strFHName = ""

    ' Bind to the Exchange Server
    iServer.DataSource.Open strComputerName

    Set RootDSE = GetObject("LDAP://" + iServer.DirectoryServer + "/RootDSE")
    strPath = "LDAP://" & iServer.DirectoryServer & "/" & RootDSE.Get("configurationNamingContext")

    ' Set the Provider for the connection object
    conn.Provider = "ADsDSOObject"

    'You will need to provide login credentials if you are not logged in
    'with an administrator security context.

    ' Open connection
    conn.Open

    ' Set command to connection object
    Set comm.ActiveConnection = conn

    comm.CommandText = "<" & strPath & ">" & ";(objectClass=msExchPFTree);ADsPath,distinguishedName,Name;subtree"

    ' Execute command
    Set rs = comm.Execute

    ' Get the Default FolderTreeHierarcy
    Do While Not (rs.EOF)
        'You can print access folder tree information here
        'Debug.Print rs.Fields("ADsPath").Value
        'Debug.Print rs.Fields("distinguishedName")
        'Debug.Print rs.Fields("Name")
        strDNFolder = rs.Fields("distinguishedName")
        'cut the folder name to get the Folder Hierarchies
        strFHName = Mid(strDNFolder, InStr(2, strDNFolder, "CN="))
        If strFHName <> "" Then
            Exit Do
        Else
            rs.MoveNext
        End If
    Loop
    ' test if the URL to the FolderTreeHierarcy is empty
    If strFHName = "" Then
        Debug.Print "No Folder Hierarchy Name Found."
    End If

    'Cleanup
    Set RootDSE = Nothing
    Set conf = Nothing

    Set conn = Nothing
    Set comm = Nothing
    Set rs = Nothing
    Set iServer = Nothing

End Sub

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Creating a Folder Tree

The following example creates a folder tree in the Web Storage System. See Web Storage System Configuration for an explanation of the folder tree.

Visual Basic

'//////////////////////////////////////////////////////////////////////////////////
'// Function:   CreatePublicFolderTree
'// Purpose:    To create a new PublicFolderTree with a given name
'// Input:      strFolderName = contains the name of the new folder to be created
'//             strAdminGroup = contains the name of the Admin Group to place the Folder Tree in
'//             strOrganization = contains the name of the Exchange Organization
'//             strDomain = contains the domain components of the LDAP path, eg: "DC=microsoft,DC=com"
'//             strFolderUrl (Optional ByRef) = contains the URL to the new folder created;
'//
'//////////////////////////////////////////////////////////////////////////////////

Public Sub CreatePublicFolderTree(ByVal strFolderName As String, _
                                             ByVal strAdminGroup As String, _
                                             ByVal strOrganization As String, _
                                             ByVal strDomain As String, _
                                             Optional ByRef strFolderURL As String)
    On Error Resume Next
    Dim iServer         As New CDOEXM.ExchangeServer
    Dim iPFTree         As New CDOEXM.FolderTree

    ' Build the URL to the PublicFolderTree
    strFolderURL = "LDAP://CN=" + strFolderName + _
                         ",CN=Folder Hierarchies" + _
                         ",CN=" + strAdminGroup + _
                         ",CN=Administrative Groups" + _
                         ",CN=" + strOrganization + _
                         ",CN=Microsoft Exchange,CN=Services,CN=Configuration," + strDomain

    ' Set the name of the PublicFolderTree
    iPFTree.name = strFolderName

    ' Save the PublicFolderTree
    iPFTree.DataSource.SaveTo strFolderURL

    ' Cleanup
    Set iServer = Nothing
    Set iPFTree = Nothing

End Sub

The preceding function calls GetFolderTreeURL to build a proper URL for creating a folder tree. See Retrieving Folder Tree URLs for a description of the function call GetFolderTreeURL().

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Deleting a Folder Tree

The following example deletes a folder tree from the Web Storage System. See Web Storage System Configuration for an explanation of the folder tree.

Visual Basic

'//////////////////////////////////////////////////////////////////////////////////
'// Function:   DeletePublicFolderTree
'// Purpose:    To delete a Public Folder Tree
'// Input:      strFolderName = contains the name of the folder tree to be deleted
'//             strAdminGroup = contains the name of the Admin Group the Folder Tree is in
'//             strOrganization = contains the name of the Exchange Organization
'//             strDomain = contains the domain components of the LDAP path, eg: "DC=microsoft,DC=com"
'//
'//////////////////////////////////////////////////////////////////////////////////

Public Sub DeletePublicFolderTree(ByVal strFolderName As String, _
                                  ByVal strAdminGroup As String, _
                                  ByVal strOrganization As String, _
                                  ByVal strDomain As String)
    On Error Resume Next
    Dim iServer         As New CDOEXM.ExchangeServer
    Dim iPFTree         As New CDOEXM.FolderTree
    Dim strFolderURL    As String
    Dim strFHName       As String

    ' Build the URL to the PublicFolderTree
    strFolderURL = "LDAP://CN=" + strFolderName + _
                         ",CN=Folder Hierarchies" + _
                         ",CN=" + strAdminGroup + _
                         ",CN=Administrative Groups" + _
                         ",CN=" + strOrganization + _
                         ",CN=Microsoft Exchange,CN=Services,CN=Configuration," + strDomain

    ' Bind to the Public Folder Tree
    iPFTree.DataSource.Open strFolderURL

    ' Delete the Public Folder Tree
    iPFTree.DataSource.Delete

    ' Cleanup
    Set iServer = Nothing
    Set iPFTree = Nothing

End Sub

The preceding example needs to build a proper URL for creating a folder tree. See Retrieving Folder Tree URLs for a description of the function call GetFolderTreeURL().

Deleting a folder tree will fail if there are any public stores still associated with the folder tree object when a request is made.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Creating a Storage Group

The following example creates a storage group. See Server and Recipient Management for further information.

Visual Basic

'//////////////////////////////////////////////////////////////////////////////////
'// Function:   CreateNewStorageGroup
'// Purpose:    To create a new storage group with a given name
'// Input:      strSGName = contains name of the new storage group to be created
'//             strComputerName = contains the name of the Exchange 2000 server
'//             strSGUrl (Optional ByRef) = contains the URL to the new storage group created;
'//
'//////////////////////////////////////////////////////////////////////////////////

Public Sub CreateNewStorageGroup(ByVal strSGName As String, _
                                      ByVal strComputerName As String, _
                                      Optional ByRef strSGUrl As String)
    On Error Resume Next
    Dim iServer         As New CDOEXM.ExchangeServer
    Dim iStGroup        As New CDOEXM.StorageGroup
    Dim strTemp         As String

    ' Set the name of the StorageGroup
    iStGroup.Name = strSGName

    ' Bind to the Exchange Server
    iServer.DataSource.Open strComputerName

    'cut out the Storage Group name from URL
    strTemp = iServer.StorageGroups(0)
    strTemp = Mid(strTemp, InStr(2, strTemp, "cn"))
    ' Build the URL to the StorageGroup
    strSGUrl = "LDAP://" & iServer.DirectoryServer & "/CN=" & strSGName & "," & strTemp

    ' Save the StorageGroup
    iStGroup.DataSource.SaveTo strSGUrl

    ' Cleanup
    Set iServer = Nothing
    Set iStGroup = Nothing

End Sub

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Deleting a Storage Group

The following example deletes a storage group. See Server and Recipient Management for further information.

Visual Basic

'//////////////////////////////////////////////////////////////////////////////////
'// Function:   DeleteStorageGroup
'// Purpose:    To delete a storage group
'// Input:      strSGName = contains the name of the storage group to be deleted
'//             strComputerName = contains the name of the Exchange 2000 server
'//
'// Notes:      Dismount is performed automatically when deleted.
'//
'//////////////////////////////////////////////////////////////////////////////////

Public Sub DeleteStorageGroup(ByVal strSGName As String, _
                                   ByVal strComputerName As String)
    On Error Resume Next
    Dim iServer         As New CDOEXM.ExchangeServer
    Dim iStGroup        As New CDOEXM.StorageGroup
    Dim arrStGroup()    As Variant
    Dim strSGUrl        As String
    Dim i               As Integer

    strSGUrl = ""

    ' Bind to the Exchange Server
    iServer.DataSource.Open strComputerName

    ' Set variant array to the ExchangeServer.StorageGroups
    arrStGroup = iServer.StorageGroups

    ' Look for a Storage Group with strSGName name in the StorageGroups array
    For i = 0 To UBound(arrStGroup)
        If InStr(1, UCase(arrStGroup(i)), UCase(strSGName)) <>   0 Then
            strSGUrl = arrStGroup(i)
        End If
    Next
    ' Verify if StorageGroup was found
    If strSGUrl <> "" Then
        ' Bind to the StorageGroup
        iStGroup.DataSource.Open "LDAP://" & iServer.DirectoryServer & "/" & strSGUrl

        ' Delete the StorageGroup
        iStGroup.DataSource.Delete
    End If

    ' Cleanup
    Set iServer = Nothing
    Set iStGroup = Nothing

End Sub

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Creating a Public Store

The code in the following example creates a public store in a storage group. Note that when you are creating a public store, you must specify a folder tree. The folder tree specifies where the data in the store is to appear in the Web Storage System. See Web Storage System Configuration for more information.

Visual Basic

'//////////////////////////////////////////////////////////////////////////////////
'// Function:   CreateNewPublicStore
'// Purpose:    To create a new PublicStoreDB with a given name
'// Input:      strPSName = contains the name of the new PublicStoreDB to be created
'//             strFolderName = contains the name of the related Public Folder
'//             strComputerName = contains the name of the Exchange 2000 server
'//             blnMount (Optional) = True if the new PublicStoreDB will be mounted after creation
'//                                 = False if the new PublicStoreDB will not be mounted
'//             strSGName (Optional) = contains the name of the storage group to create the New PublicStoreDB in;
'//                                    if it's empty then the new PublicStoreDB will be created in the default Storage Group
'//             strMDBUrl (Optional ByRef) = contains the URL to the new PublicStoreDB created;
'//
'//////////////////////////////////////////////////////////////////////////////////

Sub CreateNewPublicStore(ByVal strPSName As String, _
                              ByVal strFolderName As String, _
                              ByVal strComputerName As String, _
                              Optional ByVal blnMount As Boolean, _
                              Optional ByVal strSGName As String, _
                              Optional ByRef strPSUrl As String)

    Dim iServer         As New CDOEXM.ExchangeServer
    Dim iPbStoreDB      As New CDOEXM.PublicStoreDB
    Dim arrStGroup()    As Variant
    Dim i               As Integer
    Dim strTemp         As String
    Dim strFolderURL    As String
    Dim strFHName       As String

    ' Bind to the Exchange Server
    iServer.DataSource.Open strComputerName

    ' Get the FolderTreeHierarcy to build the URL to the Public Folder
    GetFolderTreeURL strComputerName, strFHName

    ' Build the URL to the PublicFolderTree
    strFolderURL = "LDAP://" & iServer.DirectoryServer & "/CN=" & strFolderName & "," & strFHName

    ' Set the variant array to the array of StorageGroups from Server object
    arrStGroup = iServer.StorageGroups
    ' Start to build the URL to the PublicStore - first part
    strTemp = "LDAP://" & iServer.DirectoryServer & "/CN=" & strPSName & ","

    ' Set the name of the PublicStoreDB
    iPbStoreDB.Name = strPSName
    ' Set the name of the PublicFolderTree
    iPbStoreDB.FolderTree = strFolderURL

    ' Verify if the StorageGroup strSGName exist in the StorageGroups array
    If strSGName = "" Then
        ' Finish to build the URL to the PublicStoreDB -  add last part
        strPSUrl = strTemp & iServer.StorageGroups(0)
    Else
        For i = 0 To UBound(arrStGroup)
            If InStr(1, arrStGroup(i), strSGName) <> 0 Then
                ' Finish to build the URL to the PublicStoreDB -  add last part
                strPSUrl = strTemp & arrStGroup(i)
            End If
        Next
    End If

    ' Save the PublicStoreDB
    iPbStoreDB.DataSource.SaveTo strPSUrl

    ' Mount the PublicStoreDB if thr blnMount is True
    If blnMount = True Then
        iPbStoreDB.Mount
    End If

    ' Cleanup
    Set iServer = Nothing
    Set iPbStoreDB = Nothing

End Sub

The preceding sample calls GetFolderTreeURL(). This retrieves the folder tree full URL that is used to specify the location of the store data in the Web Storage System. See Retrieving Folder Tree URLs for an explanation of GetFolderTreeURL.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Deleting a Public Store

The code in the following example deletes a public store in a storage group. The function searches the server for the specified storage group from which to delete the public store.

Visual Basic

'//////////////////////////////////////////////////////////////////////////////////
'// Function:   DeletePublicStore
'// Purpose:    To delete a PublicStoreDB with a given name
'// Input:      strPSName = contains the name of the PublicStoreDB to be deleted
'//             strComputerName = contains the name of the Exchange 2000 server
'//             strSGName (Optional) = contains the name of the storage group where PublicStoreDB is located;
'//                                    if it is empty then Storage Group will be considered the first one in the list
'//
'// Notes:      It is not necessary to dismount the store. The store will automatically be
'//             dismounted before deletion.
'//
'//////////////////////////////////////////////////////////////////////////////////

Sub DeletePublicStore(ByVal strPSName As String, _
                           ByVal strComputerName As String, _
                           Optional ByVal strSGName As String)
    Dim iServer         As New CDOEXM.ExchangeServer
    Dim iPbStoreDB      As New CDOEXM.PublicStoreDB
    Dim arrStGroup()
    Dim i               As Integer
    Dim strTemp         As String
    Dim strFolderURL    As String
    Dim strFHName       As String
    Dim strPSUrl        As String

    ' Bind to the Exchange Server
    iServer.DataSource.Open strComputerName

    ' Set the variant array to the array of StorageGroups from Server object
    arrStGroup = iServer.StorageGroups

    ' Start to build the URL to the PublicStore - first part
    strTemp = "LDAP://" & iServer.DirectoryServer & "/CN=" & strPSName & ","

    ' Verify if the StorageGroup strSGName exist in the StorageGroups array
    If strSGName = "" Then
        ' Finish to build the URL to the PublicStoreDB -  add last part
        strPSUrl = strTemp & iServer.StorageGroups(0)
    Else
        For i = 0 To UBound(arrStGroup)
            If InStr(1, arrStGroup(i), strSGName) <> 0 Then
                ' Finish to build the URL to the PublicStoreDB -  add last part
                strPSUrl = strTemp & arrStGroup(i)
            End If
        Next
    End If

    ' Bind to the PublicStoreDB
    iPbStoreDB.DataSource.Open strPSUrl

    ' Delete the PublicStoreDB
    iPbStoreDB.DataSource.Delete

    ' Cleanup
    Set iServer = Nothing
    Set iPbStoreDB = Nothing

End Sub

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Creating a Mailbox Store

The code in the following example creates a mailbox store in a storage group. Note that when you are creating a mailbox store, you must specify a public store. See Web Storage System Configuration for more information.

Visual Basic

'//////////////////////////////////////////////////////////////////////////////////
'// Function:   CreateNewMailboxStoreDB
'// Purpose:    To create a new Mailbox Store (MDB) with a given name
'// Input:      strMDBName = contains the name of the new MDB to be created
'//             blnMount = True if the new MDB will be mounted after creation or False
'//             if the new MDB will not be mounted
'//             strComputerName = contains the name of the Exchange 2000 server
'//             strSGName (Optional) = contains the name of the storage group to create
'//             the new MDB in; if it is empty then the new MDB will be created in the
'//             default Storage Group
'//             strMDBUrl (Optional ByRef) = contains the URL to the new MDB created;
'//
'//////////////////////////////////////////////////////////////////////////////////

Public Sub CreateNewMailboxStoreDB(ByVal strMDBName As String, _
                                        ByVal strComputerName As String, _
                                        Optional ByVal blnMount As Boolean, _
                                        Optional ByVal strSGName As String, _
                                        Optional ByRef strMDBUrl As String)

    Dim iServer         As New CDOEXM.ExchangeServer
    Dim iMDB            As New CDOEXM.MailboxStoreDB
    Dim arrStGroup()    As Variant
    Dim i               As Integer
    Dim strTemp         As String

    ' Set the name of the MailboxStoreDB
    iMDB.Name = strMDBName

    ' Bind to the Exchange Server
    iServer.DataSource.Open strComputerName

    ' Start to build the URL to the MailboxStoreDB - first part
    strTemp = "LDAP://" & iServer.DirectoryServer & "/" & "cn=" & strMDBName & ","

    ' Set variant array to the ExchangeServer.StorageGroups
    arrStGroup = iServer.StorageGroups

    ' Look in the StorageGroups array if the StorageGroup with strSGName exists
    If strSGName = "" Then
        ' Finish to build the URL to the MailboxStoreDB - add last part
        strMDBUrl = strTemp & iServer.StorageGroups(0)
    Else
        For i = 0 To UBound(arrStGroup)
            If InStr(1, UCase(arrStGroup(i)), UCase(strSGName)) <> 0 Then
                strMDBUrl = arrStGroup(i)
            End If
        Next
        If strMDBUrl <> "" Then
            ' Finish to build the URL to the MailboxStoreDB - add last part
            strMDBUrl = strTemp & strMDBUrl
        End If
    End If

    ' Save the New MailboxStoreDB
    iMDB.DataSource.SaveTo strMDBUrl

    ' Mount the MailboxStoreDB if blnMount is True
    If blnMount = True Then
        iMDB.Mount
    End If

    ' Cleanup
    Set iServer = Nothing
    Set iMDB = Nothing

End Sub

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Deleting a Mailbox Store

The code in the following example deletes a mailbox store in a storage group. The function searches the server for the specified storage group from which to delete the mailbox store. The delete request will fail if the mailbox store still contains mailboxes.

Visual Basic

'//////////////////////////////////////////////////////////////////////////////////
'// Function:   DeleteMailboxStoreDB
'// Purpose:    To delete a Mailbox Store (MDB)
'// Input:      strMDBName = contains the name of the MDB to be deleted
'//             strSGName = contains the name of the storage group that contains the MDB
'//             strComputerName = contains the name of the Exchange 2000 server
'//
'// Notes:      Dismount is performed automatically when deleted.
'//
'//////////////////////////////////////////////////////////////////////////////////

Public Sub DeleteMailboxStoreDB(ByVal strMDBName As String, _
                                     ByVal strSGName As String, _
                                     ByVal strComputerName As String)

    Dim iServer         As New CDOEXM.ExchangeServer
    Dim iMDB            As New CDOEXM.MailboxStoreDB
    Dim arrStGroup()
    Dim i               As Integer
    Dim strTemp         As String
    Dim strMDBUrl       As String

    ' Bind to the Exchange Server
    iServer.DataSource.Open strComputerName

    ' Build the first part of the URL to the MailboxStoreDB
    strTemp = "LDAP://" & iServer.DirectoryServer & "/" & "cn=" & strMDBName & ","

    ' Set variant array to the ExchangeServer.StorageGroups
    arrStGroup = iServer.StorageGroups

    ' Look in the StorageGroups array if the StorageGroup with strSGName exists
    If strSGName = "" Then
        ' Add last part to the URL to the MailboxStoreDB
        strMDBUrl = strTemp & iServer.StorageGroups(0)
    Else
        For i = 0 To UBound(arrStGroup)
            If InStr(1, UCase(arrStGroup(i)), UCase(strSGName)) <> 0 Then
                strMDBUrl = arrStGroup(i)
            End If
        Next
        If strMDBUrl <> "" Then
            ' Add last part to the URL to the MailboxStoreDB
            strMDBUrl = strTemp & strMDBUrl
        End If
    End If

    ' Bind to the MailboxStoreB
    iMDB.DataSource.Open strMDBUrl  ', , , adCreateOverwrite

    ' Delete the MailboxStoreDB
    iMDB.DataSource.Delete

    ' Cleanup
    Set iServer = Nothing
    Set iMDB = Nothing

End Sub

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Recipient Management Tasks

The tasks in this section demonstrate the use of the CDO for Exchange Management (CDOEXM) aggregated interfaces to create and manage recipients in Microsoft® Exchange 2000 Server. Click the following links to read the topics:

Creating a Mail-Enabled Recipient

Creating a Mailbox-Enabled Recipient

Creating a Recipient Using ADSI

Enabling Immediate Logon for New Recipients

Disabling a Mail Recipient

Moving a Mailbox

Deleting a Mailbox

Setting Mailbox Storage Limits

Controlling Mailbox Cleanup

Enumerating Users

Enumerating Groups

Enumerating Contacts

Setting Proxy Addresses

Building a Restricted Address List

Enabling a Folder for Mail

Finding the Home Server/Store for a Mailbox with ADSI

Enumerating a User's Distribution Lists

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Creating a Mail-Enabled Recipient

To create a mail-enabled recipient, you must first create an object that supports the IMailRecipient interface:

  • Person
  • Folder
  • ADSI Contact (IADS)
  • ADSI Group (IADSGroup)
  • ADSI User (IADSUser)

In most cases, you create an instance of a Person object. Note that if the user does not have an Exchange mailbox, you must set his or her address by using the IMailRecipient.MailEnable method.

Example (CDOEXM)

This example creates a mail recipient who can access mail through HTTP. The recipient is limited to sending and receiving messages no larger than 50 KB. The example uses the CreateUserURL function, which is described in the topic Creating a User URL.

Visual Basic

Sub MailEnableCDOPerson(strUserName As String, _
                             strTargetMailAddress As String, _
                             strDomain As String)

    Dim oPerson             As New CDO.Person
    Dim oRecipient          As CDOEXM.IMailRecipient

    'Target address should look like this
    'strTargetMailAddress = strLastName & "@somewhere.com"

    ' get the user
    oPerson.DataSource.Open "LDAP://CN=" + strUserName + ",CN=users," + strDomain

    ' MailEnable
    Set oRecipient = oPerson
    oRecipient.MailEnable strTargetMailAddress

    oPerson.DataSource.Save

    MsgBox strUserName + " mail enabled successfully"

    'CleanUp
    Set oPerson = Nothing
    Set oRecipient = Nothing

End Sub

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Creating a Mailbox-Enabled Recipient

The following example creates a new recipient and an accompanying mailbox. The IMailboxStore interface is aggregated onto the Person object. This allows the person information to be used when creating the mailbox.

Example (CDOEXM)

Create a mailbox for a mail recipient. The example uses the CreateUserURL subroutine, which is described in the topic Creating a User URL.

Visual Basic

Sub CreateMailboxCDOPerson(strFirstName As String, _
                                   strLastName As String, _
                                   strHomeMDBUrl As String)
'strHomeMDBUrl should look like this
'strHomeMDBUrl = "CN=Mailbox Store (MYSTORE),CN=First Storage Group,
'                 CN=InformationStore,CN=MYSTORE,CN=Servers,
'                 CN=First Administrative Group,CN=Administrative Groups,
'                 CN=IASI,CN=Microsoft Exchange,CN=Services,CN=Configuration,
'                 DC=mydomain,DC=extest,DC=microsoft,DC=com"

    Dim oPerson         As New CDO.Person
    Dim oMailbox        As CDOEXM.IMailboxStore
    Dim strUserName     As String
    Dim strURL          As String
    Dim strContainerName As String

    strUserName = strFirstName & strLastName

    strContainerName = "Users"
    ' Create URL for the user
    CreateUserURL strURL, strContainerName, False, strUserName

    oPerson.FirstName = strFirstName
    oPerson.LastName = strLastName

    oPerson.DataSource.SaveTo strURL

    ' Create Mailbox
    Set oMailbox = oPerson
    oMailbox.CreateMailbox strHomeMDBUrl

    ' Save
    oPerson.DataSource.Save

    'CleanUp
    Set oPerson = Nothing
    Set oMailbox = Nothing

End Sub

VBScript

Sub CDOCreateMailBoxRecipient(MDBName, _
                              domainName, _
                              exchangeOrg, _
                              adminGroup, _
                              storageGroup, _
                              storeName, _
                              emailname, _
                              firstName, _
                              lastName)

' MDBName   - the MDB name, for example "MyMDB6"
' domainName   - the server's domain, for example "MYDOMAIN3.microsoft.com"
' exchangeOrg  - the Exchange organization housing the mailbox store. For example "First Organization"
' adminGroup   - the Exchange administrative group name, for example "First Administrative Group"
' storageGroup - the storage group for the mailbox store, for example "First Storage Group"
' storeName    - the mailbox store name, for example "Mailbox Store (SERVERNAME)"
' emailname    - the user's e-mail name, for example "jamessmith"
' firstName    - the user's first name, for example "James"
' lastName     - the user's last name, for example "Smith"

 Dim objPerson
 Set objPerson = CreateObject("CDO.Person")
 Dim objMailbox

 Dim domTokens
 domTokens     = split(domainName,".",-1,1)
 domainDN      = join(domTokens,",dc=")
 domainDN      = "dc=" & domainDN

 ' First, create the user in Active Directory
 objPerson.FirstName = FirstName
 objPerson.LastName  = LastName
 objPerson.Fields("userPrincipalName") = LastName
 objPerson.Fields("userAccountControl") = 512
 objPerson.Fields("userPassword") = "password"
 objPerson.Fields.Update
 objPerson.DataSource.SaveTo "LDAP://CN=" + MDBName + _
                            ",CN=" + emailname + _
                            ",CN=users," + domainDN

 ' Now, create mailbox in specified location.

 Set objMailbox = objPerson.GetInterface("IMailboxStore")
 objMailbox.CreateMailbox "LDAP://CN=" + _
                         MSBName + _
                         ",CN=" + _
                         StoreName + _
                         ",CN=" + _
                         StorageGroup + ",CN=InformationStore,CN=" + _
                         ServerName + _
                         ",CN=Servers,CN=" + _
                         AdminGroup + "," + _
                         "CN=Administrative Groups,CN=" + _
                         ExchangeOrg + "," + _
                         "CN=Microsoft Exchange,CN=Services," + _
                         "CN=Configuration," + domainDN

 objPerson.DataSource.Save

End Sub

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Creating a Recipient Using ADSI

The following Active Directory™ Service Interfaces (ADSI) example creates a new mail recipient. The accompanying mailbox is created using a CDO for Exchange Management (CDOEXM) interface aggregated onto the ASDI.user object.

Example

Create a mailbox for a mail recipient using ADSI.

Visual Basic

Sub ADSICreateMailBoxRecipient(MDBName As String, _
                               StorageGroup As String, _
                               Server As String, _
                               AdminGroup As String, _
                               Organization As String, _
                               DomainName As String, _
                               emailname As String, _
                               FirstName As String, _
                               LastName As String)

'MDBName is something like "MyMDB6"
'DomainName is something like "DC=MYDOMAIN3,DC=microsoft,DC=com"
'emailname is something like "jamessmith"

'this assumes the MDB to be a mailbox store.

Dim objUser As IADsUser
Dim objContainer As IADsContainer
Dim objMailbox As CDOEXM.IMailboxStore
Dim recipname As String, recip As String

recip = "CN=" & emailname

' get the container
Set objContainer = GetObject("LDAP://CN=users," + DomainName)

' create a recipient
Set objUser = objContainer.Create("User", recip)
objUser.Put "samAccountName", emailname
objUser.Put "sn", LastName
objUser.Put "givenName", FirstName
objUser.Put "userPrincipalName", emailname

objUser.SetInfo
objUser.SetPassword "password"  'let user change it later
objUser.AccountDisabled = False

Set objMailbox = objUser

'Create a mailbox for the recipient
'You cannot create a mailbox using ADSI, so use CDOEXM

objMailbox.CreateMailbox "LDAP://CN=" + MDBName + _
                               ",CN=" + StorageGroup + _
                               ",CN=InformationStore" + _
                               ",CN=" + Server + _
                               ",CN=Servers" + _
                               ",CN=" + AdminGroup + _
                               ",CN=Administrative Groups" + _
                               ",CN=" + Organization + _
                               ",CN=Microsoft Exchange,CN=Services" + _
                               ",CN=Configuration," + DomainName
objUser.SetInfo

End Sub

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Enabling Immediate Logon for New Recipients

When an application creates a mail recipient using Collaboration Data Objects (CDO) or Active Directory™ Service Interfaces (ADSI), there will be a delay before the new recipient can log on to the system. This delay is caused by the normal latency of the Microsoft® Exchange Recipient Update Service, and may be from 2 to 30 minutes, depending on server configuration and load.

To enable immediate logon for new recipients, your application can set the msExchUserAccountControl Microsoft® Active Directory™ object on the user object. Set the object value to 2 to enable the user logon. This is the same object and value set by the Recipient Update Service.

If you are creating a new recipient and a new mailbox, first create the recipient without msExchUserAccountControl, and then create the mailbox. Enable the user for immediate logon only after both the recipient and mailbox have been successfully created.

You can set this using the IPerson.Fields property, or you can use ADSI. The following example uses ADSI.

Visual Basic

Sub ADSICreateMailBoxRecipientImmediateLogon(MDBName As String, _
                               StorageGroup As String, _
                               Server As String, _
                               AdminGroup As String, _
                               Organization As String, _
                               DomainName As String, _
                               emailname As String, _
                               FirstName As String, _
                               LastName As String)

'MDBName is something like "MyMDB6"
'DomainName is something like "DC=MYDOMAIN3,DC=microsoft,DC=com"
'emailname is something like "jamessmith"

'this assumes the MDB to be a mailbox store.

Dim objUser As IADsUser
Dim objContainer As IADsContainer
Dim objMailbox As CDOEXM.IMailboxStore
Dim recipname As String, recip As String

recip = "CN=" & emailname

' get the container
Set objContainer = GetObject("LDAP://CN=users," + DomainName)

' create a recipient
Set objUser = objContainer.Create("User", recip)
objUser.Put "samAccountName", emailname
objUser.Put "sn", LastName
objUser.Put "givenName", FirstName
objUser.Put "userPrincipalName", emailname

objUser.SetInfo
objUser.SetPassword "password"  'let user change it later
objUser.AccountDisabled = False

Set objMailbox = objUser

'Create a mailbox for the recipient
'You cannot create a mailbox using ADSI, so use CDOEXM

objMailbox.CreateMailbox "LDAP://CN=" + MDBName + _
                               ",CN=" + StorageGroup + _
                               ",CN=InformationStore" + _
                               ",CN=" + Server + _
                               ",CN=Servers" + _
                               ",CN=" + AdminGroup + _
                               ",CN=Administrative Groups" + _
                               ",CN=" + Organization + _
                               ",CN=Microsoft Exchange,CN=Services" + _
                               ",CN=Configuration," + DomainName
objUser.SetInfo

' enable immediate-logon for the user
objUser.Put "msExchUserAccountControl", 2

objUser.SetInfo

End Sub

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Disabling a Mail Recipient

Call the IMailRecipient.MailDisable method to disable a mail recipient. The IMailRecipient interface is aggregated onto the Person object.

Example

The example uses the CreateUserURL function, which is described in the topic Creating a User URL.

Visual Basic

Sub MailDisableCDOPerson(strUserName As String, strDomain As String)

    Dim oPerson         As New CDO.Person
    Dim oRecipient      As CDOEXM.IMailRecipient
    Dim strURL          As String

    ' Create URL for the user
    strURL = "LDAP://CN=" + strUserName + ",CN=Users," + strDomain

    Set oPerson = New CDO.Person
    ' Bind
    oPerson.DataSource.Open strURL

    ' MailDisable
    Set oRecipient = oPerson
    oRecipient.MailDisable

    ' Save
    oPerson.DataSource.Save

    'CleanUp
    Set oPerson = Nothing
    Set oRecipient = Nothing

End Sub

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Moving a Mailbox

The following examples move a mailbox. Note that the second private mailbox store has already been created. Lightweight Directory Access Protocol (LDAP) is used to access Active Directory. Modifications in Microsoft® Exchange 2000 Server are handled behind the scenes as part of CDO for Exchange Management (CDOEXM).

Example (CDO)

Visual Basic

Sub CDOMove_Mailbox(MDBName As String, _
                    DomainName As String, _
                    recipname As String, _
                    Moveto_MDB As String, _
                    Moveto_StorageGroup As String, _
                    Moveto_Server As String, _
                    Moveto_AdminGroup As String, _
                    Organization As String)

'MDBName is something like "MyMDB6"
'DomainName is something like "DC=MYDOMAIN3,DC=microsoft,DC=com"
'recipname is is the e-mail alias (eg. "jamessmith)."
'This assumes you have created the MDB Moveto_MDB (with a name like "PrivateMDB2")

Dim objPerson As New CDO.Person
Dim objMailbox As CDOEXM.IMailboxStore

On Error GoTo Error

objPerson.DataSource.Open "LDAP://CN=" + recipname + _
                            ",CN=users," + DomainName

Set objMailbox = objPerson
If objMailbox.HomeMDB = "" Then
   Debug.Print "No mailbox to move."
Else
  Debug.Print "Current MDB: " + objMailbox.HomeMDB
  'Moveto_MDB is the MDB name to move the mailbox to (eg. PrivateMDB2)

  objMailbox.MoveMailbox "LDAP://CN=" + Moveto_MDB + _
                               ",CN=" + Moveto_StorageGroup + _
                               ",CN=InformationStore" + _
                               ",CN=" + Moveto_Server + _
                               ",CN=Servers" + _
                               ",CN=" + Moveto_AdminGroup + _
                               ",CN=Administrative Groups" + _
                               ",CN=" + Organization + _
                               ",CN=Microsoft Exchange,CN=Services" + _
                               ",CN=Configuration," + DomainName
  objPerson.DataSource.Save
  Debug.Print "Mailbox has been moved to " + Moveto_MDB + " successfully."
End If
GoTo Ending

Error:
If Err.Number = -2147016656 Then
   Debug.Print "Recipient " + recipname + " does not exist in the default container."
   MsgBox "Recipient " + recipname + " is not found."
   Err.Clear
Else
   MsgBox "Run time error: " + Str(Err.Number) + " " + Err.Description
   Err.Clear
End If

Ending:
End Sub

Example (ADSI)

Visual Basic

Sub ADSIMove_Mailbox(MDBName As String, _
                     DomainName As String, _
                     recipname As String, _
                     Moveto_MDB As String, _
                     Moveto_StorageGroup As String, _
                     Moveto_Server As String, _
                     Moveto_AdminGroup As String, _
                     Organization As String)

'MDBName is something like "MyMDB6"
'DomainName is something like "DC=MYDOMAIN3,DC=microsoft,DC=com"
'recipname is is the e-mail alias (eg. "jamessmith)."
'This assumes you have created the MDB Moveto_MDB in the same storage group.

Dim objUser As IADsUser
Dim objMailbox As CDOEXM.IMailboxStore

On Error GoTo Error

Set objUser = GetObject("LDAP://CN=" + recipname + _
                        ",CN=users," + DomainName)

Set objMailbox = objUser
If objMailbox.HomeMDB = "" Then
   Debug.Print "No mailbox to move."
Else
  Debug.Print "Current MDB: " + objMailbox.HomeMDB

  'Moveto_MDB is the MDB name to move the mailbox to (eg. PrivateMDB2)

  objMailbox.MoveMailbox "LDAP://CN=" + Moveto_MDB + _
                               ",CN=" + Moveto_StorageGroup + _
                               ",CN=InformationStore" + _
                               ",CN=" + Moveto_Server + _
                               ",CN=Servers" + _
                               ",CN=" + Moveto_AdminGroup + _
                               ",CN=Administrative Groups" + _
                               ",CN=" + Organization + _
                               ",CN=Microsoft Exchange,CN=Services" + _
                               ",CN=Configuration," + DomainName

  objUser.SetInfo
  Debug.Print "Mailbox has been moved to " + Moveto_MDB + " successfully."
End If
GoTo Ending

Error:
If Err.Number = -2147016656 Then
   Debug.Print "Recipient " + recipname + " does not exist in the default container."
   MsgBox "Recipient " + recipname + " is not found."
   Err.Clear
Else
   MsgBox "Run time error: " + Str(Err.Number) + " " + Err.Description
   Err.Clear
End If

Ending:

End Sub

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Deleting a Mailbox

The following code deletes a user mailbox and account. The example uses the CreateUserURL function, which is described in the topic Creating a User URL.

Example (CDO)

Visual Basic

Sub DeleteMailboxCDOPerson(strFirstName As String, _
                                   strLastName As String)

    Dim oPerson         As New CDO.Person
    Dim oMailbox        As CDOEXM.IMailboxStore
    Dim strUserName     As String
    Dim strURL          As String
    Dim strContainerName As String

    strUserName = strFirstName & strLastName
    strContainerName = "Users"
    ' Create URL for the user
    CreateUserURL strURL, strContainerName, False, strUserName

    Set oPerson = New CDO.Person
    ' Bind
    oPerson.DataSource.Open strURL

    ' Delete Mailbox
    Set oMailbox = oPerson
    oMailbox.DeleteMailbox

    ' Save
    oPerson.DataSource.Save

    'CleanUp
    Set oPerson = Nothing
    Set oMailbox = Nothing

End Sub

Example (ADSI)

Visual Basic

Sub Delete_MailBoxADSI(MDBName As String, _
                       DomainName As String, _
                       recipname As String)

'MDBName is something like "MyMDB6"
'DomainName is something like "DC=MYDOMAIN3,DC=microsoft,DC=com"
'recipname is something like "jamessmith"

Dim objUser As IADsUser
Dim objMailbox As CDOEXM.IMailboxStore

Set objUser = GetObject("LDAP://CN=" + MDBName + _
                        ",CN=" + recipname + _
                        ",CN=users," + DomainName)

Set objMailbox = objUser
If objMailbox.HomeMDB = "" Then
   MsgBox "No mailbox found."
Else
   objMailbox.DeleteMailbox
   objUser.SetInfo
   MsgBox "Mailbox for " + recipname + " deleted successfully"
End If

End Sub

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Setting Mailbox Storage Limits

A common store policy is to limit the amount of disk space allocated for each mailbox. The IMailboxStore::StoreQuota property specifies the maximum size of the mailbox, in kilobytes. After the user reaches this limit, a warning message appears every time he or she sends a message. If the amount of disk space that the user consumes is not important, retain this property’s default value of –1.

If you do set StoreQuota, you might also set the IMailboxStore::OverQuotaLimit property. This property specifies the number of kilobytes over the StoreQuota limit that the user can go before he or she is restricted from sending mail. This is a gentle reminder to the user to clear some space in his or her mailbox.

Finally, set the IMailboxStore::HardLimit property to the number of kilobytes over the StoreQuota limit that the user can go before he or she is restricted from sending or receiving mail. This is a final notice to the user to clear some space in his or her mailbox.

Example

This example limits jamessmith to 10 MB, with a 2-MB soft limit and an additional 1-MB hard limit. He gets 13 MB before losing mail privileges.

Visual Basic

Sub Set_Limits(recipname As String, _
               DomainName As String)

    'DomainName is something like "DC=MYDOMAIN3,DC=microsoft,DC=com"
    'recipname is something like "jamessmith"

    Dim objPerson As New CDO.Person
    Dim objMailbox As CDOEXM.IMailboxStore

    objPerson.DataSource.Open "LDAP://CN=" + recipname + _
                                ",CN=users," + DomainName

    Set objMailbox = objPerson
    If objMailbox.HomeMDB = "" Then
       MsgBox "No Mailbox found."
    Else
       objMailbox.EnableStoreDefaults = False
       objMailbox.StoreQuota = 10
       objMailbox.OverQuotaLimit = 12
       objMailbox.HardLimit = 13
       objPerson.DataSource.Save
       MsgBox "Mailbox limits for " + recipname + " set successfully"
    End If

End Sub

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Controlling Mailbox Cleanup

You can automatically clean up deleted messages from mailboxes by setting the garbage collection properties on the mailbox. To limit how long the store keeps deleted mail, set the IMailboxStore::DaysBeforeGarbageCollection property to the number of days to keep the deleted mail. When no value is set, the global mailbox store setting is used.

To require that the store is backed up before it removes deleted mail, set the IMailboxStore::GarbageCollectionOnlyAfterBackup property to True.

Finally, to prevent the store from removing deleted mail, set the IMailboxStore::OverrideStoreGarbageCollection property to True.

For more information, see the DaysBeforeDeletedMailboxCleanup property on the IMailboxStoreDB interface.

Example

This example cleans up files seven days after a backup.

Visual Basic

Sub Set_Cleanup(recipname As String, _
                DomainName As String)

'DomainName is something like "DC=MYDOMAIN3,DC=microsoft,DC=com"
'recipname is something like "jamessmith"

Dim objUser As IADsUser
Dim objMailbox As CDOEXM.IMailboxStore

Set objUser = GetObject("LDAP://CN=" + recipname + _
                        ",CN=users," + DomainName)

Set objMailbox = objUser
If objMailbox.HomeMDB = "" Then
   MsgBox "No mailbox found."
Else
   objMailbox.OverrideStoreGarbageCollection = True
   objMailbox.GarbageCollectOnlyAfterBackup = True
   objMailbox.DaysBeforeGarbageCollection = 7
   'commit the changes
   objUser.SetInfo
End If

End Sub

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Enumerating Users

Example

This example lists the users in the "Users" container in the Active Directory. The example opens the user information in Active Directory by using Active Directory™ Service Interfaces (ADSI). It then uses the IMailboxStore interface aggregated onto the ADSI user object to access information in the Web Storage System.

Visual Basic

Sub List_Users(DomainName As String)

'DomainName is something like "DC=MYDOMAIN3,DC=microsoft,DC=com"

Dim objUser As IADsUser
Dim objContainer As IADsContainer
Dim objMailbox As CDOEXM.IMailboxStore
Dim i As Long
Dim name As String

On Error GoTo Error
' get the container. Note that user information may be located in
' other organizational units.
Set objContainer = GetObject("LDAP://CN=users," + DomainName)

objContainer.Filter = Array("User")
i = 0

For Each objUser In objContainer
   name = objUser.name
   name = Right(name, Len(name) - 3)
   Set objMailbox = objUser
   If objMailbox.HomeMDB = "" Then
      Debug.Print name + "   (no mailbox)"
   Else
      Debug.Print name + "   (has mailbox)"
      Debug.Print objMailbox.HomeMDB
   End If
   i = i + 1
Next
Debug.Print "Number of users found in the DS (in the default container): " + Str(i)
GoTo Ending

Error:
   Debug.Print "Failed while displaying the users in the default container."
   MsgBox "Run time error: " + Str(Err.Number) + " " + Err.Description
   Err.Clear
Ending:

End Sub

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Enumerating Groups

Example

This example lists the groups in the "Users" container in the Active Directory. This example opens group information in Active Directory by using Active Directory™ Service Interfaces (ADSI). It then uses the IMailRecipient interface aggregated onto the ADSI group object to access information about the e-mail address of the groups.

Visual Basic

Sub List_Groups(DomainName As String)

'DomainName is something like "DC=MYDOMAIN3,DC=microsoft,DC=com"

Dim objGroup As IADsGroup
Dim objContainer As IADsContainer
Dim objRecip As CDOEXM.MailRecipient
Dim i As Long
Dim name As String

On Error GoTo Error
' get the users container. Note that user information can also
' be stored in other organizational units (ou).
Set objContainer = GetObject("LDAP://CN=users," + DomainName)

objContainer.Filter = Array("Group")
i = 0

Debug.Print

For Each objGroup In objContainer
   name = objGroup.name
   name = Right(name, Len(name) - 3)
   Set objRecip = objGroup
   If objRecip.TargetAddress = "" And objRecip.X400Email = "" Then
      Debug.Print name + "   (mail disabled)"
   Else
      Debug.Print name + "   (mail enabled)"
   End If
   i = i + 1
Next
Debug.Print "Number of groups found in the DS (in the default container): " + Str(i)
GoTo Ending

Error:
   Debug.Print "Failed while displaying the groups in the default container."
   MsgBox "Run time error: " + Str(Err.Number) + " " + Err.Description
   Err.Clear
Ending:

End Sub

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Enumerating Contacts

Example

This example lists the contacts in the "Users" container in the Active Directory. The example opens contact information in Active Directory by using Active Directory™ Service Interfaces (ADSI). It then uses the IMailRecipient interface aggregated onto the ADSI contacts object to access information about the e-mail address for each contact.

Visual Basic

Sub List_Contacts(DomainName As String)

'DomainName is something like "DC=MYDOMAIN3,DC=microsoft,DC=com"

Dim objContact As IADs
Dim objContainer As IADsContainer
Dim objRecip As CDOEXM.MailRecipient
Dim i As Long
Dim name As String

On Error GoTo Error
' get the user container. Note that user information can also
' be stored in other organizational units (ou).
Set objContainer = GetObject("LDAP://CN=users," + DomainName)
objContainer.Filter = Array("Contact")
i = 0
Debug.Print
For Each objContact In objContainer
   name = objContact.name
   name = Right(name, Len(name) - 3)
   Set objRecip = objContact
   If objRecip.TargetAddress = "" And objRecip.X400Email = "" Then
      Debug.Print name + "   (mail disabled)"
   Else
      Debug.Print name + "   (mail enabled)"
   End If
   i = i + 1
Next
Debug.Print "Number of contacts found in the DS (in the default container): " + Str(i)
GoTo Ending

Error:
   Debug.Print "Failed while displaying the contacts in the default container."
   MsgBox "Run time error: " + Str(Err.Number) + " " + Err.Description
   Err.Clear

Ending:

End Sub

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Setting Proxy Addresses

Example

This example sets the proxy addresses for a mailbox-enabled user. When setting proxy addresses, you must specify a default proxy address by using all capital letters in one address. In the following example, the "X400" address is designated as the default proxy address.

Visual Basic

Sub SetProxyAddress(recipname As String, _
                    DomainName As String)

    'DomainName is something like "DC=MYDOMAIN3,DC=microsoft,DC=com"
    'recipname is something like "jamessmith"

    Dim objPerson As New CDO.Person
    Dim objMailRecip As CDOEXM.IMailRecipient
    Dim i

    objPerson.DataSource.Open "LDAP://CN=" + recipname + _
                              ",CN=users," + DomainName

    'Capitalized proxy type for proxies(1) makes it the primary (reply) address.
    'the others are recieve only.
    Dim proxies(3) As Variant
    proxies(0) = "smtp:user@secondarymailproxy.microsoft.com"
    proxies(1) = "SMTP:user@primarymailproxy.microsoft.com"
    proxies(2) = "X400:c=us;a= ;p=Domain;o=First Organization;s=user;"

    Set objMailRecip = objPerson
    objMailRecip.ProxyAddresses = proxies

    'look at the results
    Debug.Print Chr(13) + Chr(13) + Chr(13) + Chr(13) + Chr(13) 'add some space
    For i = LBound(objMailRecip.ProxyAddresses) To UBound(objMailRecip.ProxyAddresses)
      Debug.Print objMailRecip.ProxyAddresses(i)
    Next

    objPerson.DataSource.Save
    MsgBox "Proxy addresses for " + recipname + " set successfully"

End Sub

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Building a Restricted Address List

Example

This example adds to the restricted address list for a recipient. This involves setting the IMailRecipient.RestrictedAddresses property to either cdoReject or cdoAccept and adding to the IMailRecipient.RestrictedAddressList list.

Visual Basic

Note The following example uses a file URL with the Exchange OLE DB (ExOLEDB) provider. The ExOLEDB provider also supports the HTTP URL scheme. Using the HTTP URL scheme allows both client and server applications to use a single URL scheme.
Sub RestrictAddresses(DomainName As String, _
                      FolderName As String)

    'DomainName is something like "MyDomain.wherever.com"
    'FolderName is something like "Public Folders/Folder3"

    Dim objFolder As New CDO.Folder
    Dim objMailRecip As CDOEXM.IMailRecipient
    Dim fullurl As String
    Dim i

    'fullurl might look like:
    ' "file://./backofficestorage/MyDomain.wherever.com/Public Folders/Folder3"
    fullurl = "file://./backofficestorage/" + _
              DomainName + "/" + FolderName

    objFolder.DataSource.Open fullurl, , adModeReadWrite, adFailIfNotExists

    Set objMailRecip = objFolder

    ' can build an accept or reject list
    objMailRecip.restrictedAddresses = cdoReject 'reject these emails

    Dim list(3) As Variant

    list(0) = "user@" + DomainName
    list(1) = "user1@" + DomainName
    list(2) = "user2@" + DomainName

    objMailRecip.RestrictedAddressList = list
    objFolder.DataSource.Save

    'look at the results
    Debug.Print Chr(13) + Chr(13) + "View list"
    For i = LBound(objMailRecip.RestrictedAddressList) To UBound(objMailRecip.RestrictedAddressList)
      Debug.Print objMailRecip.RestrictedAddressList(i)
    Next

    MsgBox "Mailbox restrictions for " + FolderName + " set successfully"

End Sub

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Enabling a Folder for Mail

Example

This example enables a folder (mailbox) for receiving mail.

Visual Basic

Note The following example uses a file URL with the Exchange OLE DB (ExOLEDB) provider. The ExOLEDB provider also supports the HTTP URL scheme. Using the HTTP URL scheme allows both client and server applications to use a single URL scheme.
Sub EnableFolder(DomainName As String, _
                 FolderName As String)

    'DomainName is something like "MyDomain.wherever.com"
    'FolderName is something like "Public Folders/Folder3"

    Dim objFolder As New CDO.Folder
    Dim objRecip As CDOEXM.IMailRecipient
    Dim fullurl As String

    'fullurl might look like:
    ' "file://./backofficestorage/MyDomain.wherever.com/Public Folders/Folder3"
    fullurl = "file://./backofficestorage/" + _
              DomainName + "/" + FolderName

    objFolder.DataSource.Open fullurl, , adModeReadWrite, adFailIfNotExists
    Set objRecip = objFolder
    objRecip.MailEnable
    objFolder.DataSource.Save

End Sub

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Finding the Home Server/Store for a Mailbox with ADSI

Visual Basic

' Finding the Home server/store for a mailbox with ADSI
' The following sample will query Active Directory for a given mail user
' and return the Home Server/Storage Group/MDB for that mailbox
' This code can be run from any Windows 2000 or DSCLient computer
'
' Visusal Basic Project References
'  - Microsoft ActiveX Data Objects 2.5 Library
'  - Active DS Type Library

Sub UserInfo()

Dim iAdRootDSE As ActiveDs.IADs
Dim Conn As New ADODB.Connection
Dim Com As New ADODB.Command
Dim Rs As ADODB.Recordset
Dim varDomainNC As Variant
Dim strQuery As String
Dim strAlias As String
Dim varOwningServerDN As Variant
Dim iAdHomeMDB As ActiveDs.IADs
Dim iAdStorageGroup As ActiveDs.IADs
Dim iAdServer As ActiveDs.IADs

' change to the alias for the mailbox you are looking for
strAlias = "user1"

' Get the Configuration Naming Context
Set iAdRootDSE = GetObject("LDAP://RootDSE")
varDomainNC = iAdRootDSE.Get("defaultNamingContext")

' Open the Connection
Conn.Provider = "ADsDSOObject"
Conn.Open "ADs Provider"

' Build the query to find the user based on his Alias
strQuery = "<LDAP://" & varDomainNC & ">;(mailNickName=" & strAlias & ");name,homeMDB;subtree"

Com.ActiveConnection = Conn
Com.CommandText = strQuery
Set Rs = Com.execute

' Iterate through the results
While Not Rs.EOF
' Retrieve the Home MDB for the Mailbox
Set iAdHomeMDB = GetObject("LDAP://" & Rs.Fields("homeMDB"))
' Get the parent of the MDB which is the storage group
Set iAdStorageGroup = GetObject(iAdHomeMDB.Parent)
' Find the Server which owns the MDB
varOwningServerDN = iAdHomeMDB.Get("msExchOwningServer")
Set iAdServer = GetObject("LDAP://" & varOwningServerDN)

MsgBox "The mailbox store for " & Rs.Fields("name") & " is located : " & _
vbLf & iAdServer.Get("cn") & "/" & iAdStorageGroup.Get("cn") & _
"/" & iAdHomeMDB.Get("cn")

Set iAdServer = Nothing
Set iAdStorageGroup = Nothing
Set iAdHomeMDB = Nothing

Rs.MoveNext
Wend

'Clean Up
Rs.Close
Conn.Close
Set Rs = Nothing
Set Com = Nothing
Set Conn = Nothing
End Sub

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Enumerating a User's Distribution Lists

Visual Basic

'Enumerate Distribution Lists that a User is on
'This sample will list out the Groups that this User account is on.
'It does not expand the enumeration of nested Groups.
'This sample requires a reference to the following libraries:
'Active DS Type Library (activeds.tlb)
'Microsoft ActiveX Data Objects 2.5 Library (msado15.tlb)

Private Sub Main()

Dim objRootDSE As IADs
Dim objConnection As New ADODB.Connection
Dim objCommand As New ADODB.Command
Dim RS As ADODB.Recordset
Dim RS2 As ADODB.Recordset
Dim varDomainNC As Variant
Dim strQuery As String
Dim strAlias As String
Dim v As Variant
Dim x As Variant

' change to the alias for the mailbox you are looking for
strAlias = "User1"

' Get the Configuration Naming Context
Set objRootDSE = GetObject("LDAP://RootDSE")
varDomainNC = objRootDSE.Get("defaultNamingContext")

' Open the Connection
objConnection.Provider = "ADsDSOObject"
objConnection.Open "ADs Provider"

' Build the query to find the user based on the Alias
strQuery = "<LDAP://" & varDomainNC & ">;(mailNickName=" & strAlias & ");name,ADsPath,memberOf,primaryGroupID;subtree"

objCommand.ActiveConnection = objConnection
objCommand.CommandText = strQuery
Set RS = objCommand.Execute

' If we get a result then loop through the memberOf array
If Not RS.EOF Then
RS.MoveFirst
Debug.Print RS.Fields("name"), "is a member of these Groups:"
'we need to place the membersOf results in an array so that we can loop through it.
v = RS.Fields("memberOf").Value
For Each x In v
Debug.Print x
Next

'memberOf does not contain the primary group which this mailbox is
' a part of. We need to determine what that account is and list it
' We will search on objectclass = Group and then compare the user's
' primaryGroupID with the Group's primaryGroupToken. When we find a
' match then we stop
strQuery = "<LDAP://" & varDomainNC & ">;(objectclass=Group);distinguishedname,ADsPath,primaryGroupToken;subtree"
objCommand.CommandText = strQuery
Set RS2 = objCommand.Execute
RS2.MoveFirst
While Not RS2.EOF
If RS2.Fields("primaryGroupToken") = RS.Fields("primaryGroupID") Then
Debug.Print RS2.Fields("distinguishedname")
RS2.MoveLast
Else
RS2.MoveNext
End If
Wend
End If

RS.Close
RS2.Close
objConnection.Close
Set RS = Nothing
Set RS2 = Nothing
Set objCommand = Nothing
Set objConnection = Nothing
Set objRootDSE = Nothing
End Sub

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Management Tasks Using ADSI

This section contains example code for managing recipients, mailboxes, and folders using Active Directory™ Service Interfaces (ADSI). Click the links below to read the topics:

Creating a User URL

Enumerating Exchange 2000 Servers with ADSI

Manipulating Extension Attributes with ADSI

Adding/Removing a Manager Object with ADSI

Enumerating Exchange Object Properties with ADSI/ADO

Retrieving a Legacy Exchange Distinguished Name with ADSI

Finding the Exchange Organization Name Using ADSI (Visual Basic)

Finding the Exchange Organization Name Using ADSI (C++)

Finding Exchange AddressLists with ADSI

Creating a Distribution List Using CDOEXM and ADSI

Setting Message Restriction on an SMTP Virtual Server Using ADSI

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Creating a User URL

Accessing user information stored in Microsoft® Active Directory™ is accomplished by constructing a URL that uniquely identifies where the information is stored. The example code in this topic demonstrates how to construct a user URL.

The example constructs the URL string, however, the example does not create anything in Active Directory. If you use this code, you must ensure the validity of the user name and other parameters passed to the function. Your code must also verify whether the URL returned by this function refers to a valid Active Directory location.

Visual Basic

'/////////////////////////////////////////////////////////////////
'// Function:   CreateUserURL
'// Purpose:    To create a URL for a user
'// Input/Output:
'//     strUrl [out]  = contains the URL for the user;
'//     strContainer = contains the name of the container to create the user in.
'//                    If nothing passed in then user is created at domain level.
'//     IsContainerURL = True means the URL is for the user's container;
'//                         False means the URL is for a user
'//     strUSerName = contains the name of the user; if is not provided it will be created
'//
'////////////////////////////////////////////////////////////////////

Public Sub CreateUserURL(ByRef strURL As String, _
                              ByVal strContainer As String, _
                              ByVal IsContainerURL As Boolean, _
                              Optional ByRef strUserName As String) As Boolean
    On Error Resume Next

    Dim objIADs             As IADs
    Dim iADSSystem          As New ADSystemInfo
    Dim strDomainDN         As String
    Dim strDomainDNSName    As String
    Dim strContainerDN      As String
    Dim iTemp               As Integer

    Set objIADs = GetObject("LDAP://RootDSE")
    strDomainDN = objIADs.Get("defaultNamingContext")       'such as DC=mydomain,DC=microsoft,DC=com
    strDomainDNSName = iADSSystem.DomainDNSName             'such as mydnsname.microsoft.com

    'LDAP://mydomain.microsoft.com/CN=User2,CN=Users,DC=mydomain,
    'DC=extest,DC=microsoft,DC=com
     strURL = "LDAP://" & strDomainDNSName & "/"      'LDAP://mydomain.extest.microsoft.com/
     If strContainer <> "" Then
         '// If a default container then reference as a Container
         strContainerDN = "CN=" + strContainer + "," + strDomainDN
     Else
         '// If nothing passed in then create user under the domain
         strContainerDN = strDomainDN
     End If

     If Not IsContainerURL Then
         If strUserName = "" Then
            Randomize
            iTemp = Int(Rnd * 33554432)
            strUserName = "CDOUser" & "_" & Str(iTemp)
         End If
         strURL = strURL & "CN=" & strUserName & "," & strContainerDN
     Else
         strURL = strURL & strContainerDN
     End If

    'CleanUp
    Set objIADs = Nothing
    Set iADSSystem = Nothing
End Sub

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Enumerating Exchange 2000 Servers with ADSI

Visual Basic

'Enumerate Exchange 2000 servers with ADSI
'The below sample will query Active Directory using ADO for all the Exchange servers in the Forest.
'This code can be run from any Windows 2000 or DSCLient machine

    Sub main()

    Dim iAdRootDSE As IADs
    Dim Conn As New ADODB.Connection
    Dim Com As New ADODB.Command
    Dim Rs As ADODB.Recordset
    Dim varConfigNC As Variant
    Dim strQuery As String
    Dim varVersion() As Variant

    ' Get the Configuration Naming Context
    Set iAdRootDSE = GetObject("LDAP://RootDSE")
    varConfigNC = iAdRootDSE.Get("configurationNamingContext")

    ' Open the Connection
    Conn.Provider = "ADsDSOObject"
    Conn.Open "ADs Provider"

    ' Build the query to find all Exchange Servers
    strQuery = "<LDAP://" & varConfigNC & ">;(objectCategory=msExchExchangeServer);name,serialNumber;subtree"

    Com.ActiveConnection = Conn
    Com.CommandText = strQuery
    Set Rs = Com.Execute

    ' Iterate through the results
    While Not Rs.EOF
    ' serialNumber is returned as a Variant array
    varVersion = Rs.Fields("serialNumber").Value

    ' Output the name of the server and the first element of the array
    MsgBox "Server: " & Rs.Fields("name") & vbLf & "Version: " & varVersion(0)
    Rs.MoveNext
    Wend

    'Clean Up
    Rs.Close
    Conn.Close
    Set Rs = Nothing
    Set Com = Nothing
    Set Conn = Nothing

End Sub

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Manipulating Extension Attributes with ADSI

Visual Basic

' Description: Manipulating extension attributes with ADSI
'
' The purpose of this sample is to demonstrate how to query for
' mail-enabled User objects that do not have the extensionattribute2
' property set and to set the it on User object
'
' Visusal Basic Project References
'  - Microsoft ActiveX Data Objects 2.5 Library (msado15.dll)
'  - Active DS Type Library (activeds.tlb)

Sub Main()

Dim oRootDSE As IADs
Dim objUser As IADsUser
Dim oConnection As New ADODB.Connection
Dim oCommand As New ADODB.Command
Dim RS As ADODB.Recordset
Dim strQuery As String, newattrib As String
Dim varDomainNC As Variant

On Error Resume Next
' Get the Configuration Naming Context
Set oRootDSE = GetObject("LDAP://RootDSE")
varDomainNC = oRootDSE.Get("defaultNamingContext")
' Open the Connection
oConnection.Provider = "ADsDSOObject"
oConnection.Open "ADs Provider"
'Build a query to find all mail enabled Users that do not have
'extensionattribute2 set
strQuery = "<LDAP://" & varDomainNC & ">;(&(&(objectClass=user)(!(extensionAttribute2=*)))((mail=*)));adspath,cn;subtree"
oCommand.ActiveConnection = oConnection
oCommand.CommandText = strQuery
Set RS = oCommand.Execute
If RS.RecordCount = 0 Then
Debug.Print "No mailbox enabled User found to not have extension attribute 2 set"
Else
While Not RS.EOF
Set objUser = GetObject(RS.Fields("adspath"))
Debug.Print objUser.cn, " does not have extension attribe2 set"
'let's set the attribute2 to a social security number
newattrib = "111-11-1111"
objUser.Put "extensionAttribute2", newattrib
objUser.SetInfo
RS.MoveNext
Wend
End If
Set oRootDSE = Nothing
Set objUser = Nothing
RS.Close
Set RS = Nothing
End Sub

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Adding/Removing a Manager Object with ADSI

Visual Basic

    ' Description: Adding/Removing a manager object with ADSI
    '
    ' Set manager and Direct report on a User object
    '
    ' Visusal Basic Project References
    '  - Microsoft ActiveX Data Objects 2.5 Library (msado15.dll)
    '  - Active DS Type Library (activeds.tlb)

    Private Sub Main()

    Dim objRootDSE As IADs
    Dim objUser As IADsUser
    Dim objUser2 As IADsUser
    Dim objConnection As New ADODB.Connection
    Dim objCommand As New ADODB.Command
    Dim RS As ADODB.Recordset
    Dim RS2 As ADODB.Recordset
    Dim varDomainNC As Variant
    Dim strQuery As String
    Dim strAlias As String
    Dim strReportToAdd As String
    Dim strManagerAlias As String
    Dim strAliasDN As String
    Dim varExchangeSD As Variant
    Dim varReports As Variant

    On Error Resume Next

    ' change to the alias for the User to modify
    strAlias = "User1"

    ' change this to the manager's alias
    ' you want to set on the User (MR.A) you are modifying
    strManagerAlias = "User2"

    ' change this to the direct report Alias you want
    ' to add to the user (MR.A) you are modifying
    strReportToAdd = "User3"

    ' Get the Configuration Naming Context
    Set objRootDSE = GetObject("LDAP://RootDSE")
    varDomainNC = objRootDSE.Get("defaultNamingContext")

    ' Open the Connection
    objConnection.Provider = "ADsDSOObject"
    objConnection.Open "ADs Provider"

    ' Build the query to find the user (MR.A) based on his Alias
    strQuery = "<LDAP://" & varDomainNC & ">;(mailNickName=" & strAlias & ");distinguishedname,ADsPath;subtree"

    objCommand.ActiveConnection = objConnection
    objCommand.CommandText = strQuery
    Set RS = objCommand.Execute

    ' If we get a result, get the object in the directory
    If Not RS.EOF Then
    RS.MoveFirst
    Set objUser = GetObject(RS.Fields("ADsPath"))

    'Debug print the current manager for this (MR.A) User
    Debug.Print "manager for ", strAlias, " is ", objUser.Get("manager")

    'change the Manager for this User (MR.A)
    'Build the query to find the manager's user (MR.B)object
    strQuery = "<LDAP://" & varDomainNC & ">;(mailNickName=" & strManagerAlias & ");distinguishedname,ADsPath;subtree"
    objCommand.CommandText = strQuery
    Set RS2 = objCommand.Execute

    'If we get a result then set the manager property of MR.A object to
    ' the distinguishedName property of MR.B object
    If Not RS2.EOF Then

    strAliasDN = RS2.Fields("distinguishedName")
    objUser.Put "manager", strAliasDN
    objUser.SetInfo
    End If

    'Debug print the current manager for MR.A
    Debug.Print "New manager for ", strAlias, " is ", objUser.Get("manager")

    '
    ' This section will Add the new direct report
    '

    'Debug Print the current direct reports for this User object (MR.A)
    Call DisplayDirectReports(objUser, strAlias)

    ' Becuase directReports property is a calculated property and is a back link
    ' we can not modify it directly , but need to modify the user object's (strReportToAdd)
    ' manager property for the user (MR.C) we want to add as a direct report

    ' Build the query to find the direct report user based on his Alias (MR.C)
    Set RS2 = Nothing
    strQuery = "<LDAP://" & varDomainNC & ">;(mailNickName=" & strReportToAdd & ");distinguishedname,manager,ADsPath;subtree"
    objCommand.CommandText = strQuery
    Set RS2 = objCommand.Execute

    'If we get a result then set the direct report User's (MR.C)
    ' manager property
    If Not RS2.EOF Then
    RS2.MoveFirst
    Set objUser2 = GetObject(RS2.Fields("ADsPath"))

    ' set direct report's (MR.C) manager property to the
    ' distinguished name of the User object (MR.A)
    strAliasDN = RS.Fields("distinguishedName")
    objUser2.Put "manager", strAliasDN
    objUser2.SetInfo
    End If

    Call DisplayDirectReports(objUser, strAlias)

    End If

    'Clean Up
    RS.Close
    objConnection.Close
    Set RS = Nothing
    Set RS2 = Nothing
    Set objCommand = Nothing
    Set objConnection = Nothing
    Set objUser = Nothing
    Set objUser2 = Nothing
    Set objRootDSE = Nothing

End Sub

Sub DisplayDirectReports(objUser As IADsUser, strAlias As String)

    Dim varReports As Variant
    Dim i As Integer

    'Get the current direct reports for this User object into an array
    objUser.GetInfoEx Array("directReports"), 0
    varReports = objUser.GetEx("directReports")

    'Debug print the current list of direct reports
    Debug.Print "Direct reports for ", strAlias, " Currently are "
    For i = LBound(varReports) To UBound(varReports)
    Debug.Print varReports(i)
    Next i

End Sub

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Enumerating Exchange Object Properties with ADSI/ADO

Visual Basic

'
' Description: Enumerating Exchange Object Properties with ADSI/ADO
' The purpose of this sample is to aid the developer in identifying the LDAP
' properties that are being displayed by the Users and Computers snap-in
' when viewing the User objects Exchange General Tab and Exchange Advanced tabs.
' This sample requires a reference to the following libraries:
'
' Visusal Basic Project References
'  - Microsoft ActiveX Data Objects 2.5 Library (msado15.dll)
'  - Active DS Type Library (activeds.tlb)

Sub Main()

Dim oRootDSE As IADs
Dim oDomain As IADs
Dim obj As IADs
Dim objUser As IADsUser
Dim dacl As IADsAccessControlList
Dim ace As IADsAccessControlEntry
Dim oConnection As New ADODB.Connection
Dim oCommand As New ADODB.Command
Dim RS As ADODB.Recordset
Dim RS2 As ADODB.Recordset
Dim strQuery As String, strAlias As String, mystring As String
Dim varDomainNC As Variant, Desc As Variant, varReports As Variant
Dim PropArray As Variant, Prop As Variant, DescList As Variant
Dim Everyone As Boolean
Dim i As Integer

Const RIGHT_DS_DELETE = &H10000
Const RIGHT_DS_READ = &H20000
Const RIGHT_DS_CHANGE = &H40000
Const RIGHT_DS_TAKE_OWNERSHIP = &H80000
Const RIGHT_DS_MAILBOX_OWNER = &H1
Const RIGHT_DS_SEND_AS = &H2
Const RIGHT_DS_PRIMARY_OWNER = &H4

On Error Resume Next
' TODO: change to the alias for the mailbox you are looking for
strAlias = "User1"

' Get the Configuration Naming Context
Set oRootDSE = GetObject("LDAP://RootDSE")
varDomainNC = oRootDSE.Get("defaultNamingContext")
' Open the Connection
oConnection.Provider = "ADsDSOObject"
oConnection.Open "ADs Provider"

' Build the query to find the user based on his Alias
strQuery = "<LDAP://" & varDomainNC & ">;(mailNickName=" & strAlias & ");adspath;subtree"

oCommand.ActiveConnection = oConnection
oCommand.CommandText = strQuery
Set RS = oCommand.Execute
If RS.RecordCount = 0 Then
Debug.Print strAlias, " is not a valid e-mail alias"
Else
' Iterate through the results
While Not RS.EOF
' Retrieve the properties and display in debug window
Set objUser = GetObject(RS.Fields("adspath"))
Debug.Print "*************************************************"
Debug.Print "Information From the Exchange GENERAL Tab:"
Debug.Print "*************************************************"
Debug.Print "Mailbox Store:", objUser.homeMDB
Debug.Print "Alias:", objUser.mailNickname
Debug.Print "Delivery Restrictions:"
Debug.Print " Outgoing Message Size Limit:"
If objUser.submissionContlength > 0 Then
Debug.Print " No Limit: Is Not Selected"
Debug.Print " Maxumum Size KB: Is Selected"
Debug.Print " Maximum Size KB: ", objUser.submissionContlength
Else
Debug.Print " No Limit: Is selected"
Debug.Print " Maximum Size KB: Is not Selected"
End If

Debug.Print " Incoming Message Size:"
If objUser.delivContLength > 0 Then
Debug.Print " No Limit: Is Not Selected"
Debug.Print " Maximum Size: Is Selected"
Debug.Print " Maximum Size:", objUser.delivContLength
Else
Debug.Print " No Limit: Is Selected"
Debug.Print " Maximum Size: Is Not Selected"
End If

Debug.Print " Message Restriction:"
Debug.Print " Accept Messages from:"
Everyone = True
' Initialize the array of properties to pass to GetInfoEx
PropArray = Array("authOrig", "unauthOrig", "dlMemSubmitPerms", "dlMemRejectPerms")
' Make the array a single variant for passing to GetInfoEx
Prop = PropArray
objUser.GetInfoEx Prop, 0
Err.Clear
DescList = objUser.Get("dlMemSubmitPerms")
If Err.Number <> -2147463155 Then
Debug.Print " From Everyone: IS Not Selected"
Debug.Print " Only From:"
For Each Desc In DescList
' Print the descriptions
Debug.Print " ", (Desc)
Next
Everyone = False
End If
DescList = Null
Err.Clear
DescList = objUser.Get("authOrig")
If Err.Number <> -2147463155 Then
For Each Desc In DescList
' Print the descriptions
Debug.Print " ", (Desc)
Next
Everyone = False
End If
DescList = Null
Err.Clear
DescList = objUser.Get("dlMemRejectPerms")
If Err.Number <> -2147463155 Then
Debug.Print " From Everyone Except:"
For Each Desc In DescList
' Print the descriptions
Debug.Print " ", (Desc)
Next
Everyone = False
End If
DescList = Null
DescList = objUser.Get("unauthOrig")
If Err.Number <> -2147463155 Then
For Each Desc In DescList
' Print the descriptions
Debug.Print " ", (Desc)
Next
Everyone = False
End If
If Everyone = True Then
Debug.Print " From Everyone: Is Selected"
End If
Debug.Print "Delivery Options:"
Debug.Print " Delegates:"
Debug.Print " Grant Permission to:"
DescList = Null
Err.Clear
DescList = objUser.Get("publicDelegates")
If Err.Number <> -2147463155 Then
For Each Desc In DescList
' Print the descriptions
Debug.Print " ", (Desc)
Next
Else
Debug.Print " Not Set"
End If
Debug.Print " Forwarding Address:", objUser.altRecipient
If objUser.deliverAndRedirect = True Then
Debug.Print " Deliver message to both forwarding address and mailbox: Checked"
Else
Debug.Print " Deliver message to both forwarding address and mailbox: Not Checked"
End If
Debug.Print " Recipient Limits:"
Err.Clear
DescList = objUser.Get("msExchRecipLimit")
If Err.Number <> -2147463155 Then
For Each Desc In DescList
Debug.Print " Maximum users:", objUser.msExchRecipLimit
Next
Else
Debug.Print " Not Set"
End If

Debug.Print "Storage Limits:"
Debug.Print " Use mailbox store defaults:", objUser.mdbusedefaults
Debug.Print " When mailbox exceeds the indicated amount:"
Debug.Print " Issue warning at:", objUser.mdbstoragequota
Debug.Print " Prohibit send at:", objUser.mdbOverquotalimit
Debug.Print " Prohibit send and recieve at:", objUser.mdbOverhardquotalimit
Debug.Print " Maximum Size:", objUser.MaxStorage
Debug.Print " Deleted items retension:"
If objUser.deletedItemflags > 0 Then
Debug.Print " Use mailbox store defaults: is Not Checked"
Else
Debug.Print " Use mailbox store defaults: is Checked"
End If
Debug.Print " Keep deleted items for days:", objUser.garbageCollPeriod / 86400
If objUser.deletedItemflags = 3 Then
Debug.Print " Don't permenently delete until the store has been backed up: is Checked"
Else
Debug.Print " Don't permenently delete until the store has been backed up: is Not Checked"
End If
Debug.Print "*************************************************"
Debug.Print "Information From the Exchange Advanced Tab:"
Debug.Print "*************************************************"
Debug.Print "Simple Display Name:", objUser.displayNamePrintable
Debug.Print "Hide from Exchange Address list", objUser.msExchHidefromAddressLists
varReports = objUser.securityProtocol
If varReports(3) <> 0 Then
Debug.Print "Downgrade high priority mail bound for X400: Is Checked"
Else
Debug.Print "Downgrade high priority mail bound for X400: Is Not Checked"
End If
Debug.Print "Custom Attributes:"
Debug.Print " extensionAttribute1:", objUser.extensionAttribute1
Debug.Print " extensionAttribute2:", objUser.extensionAttribute2
Debug.Print " extensionAttribute3:", objUser.extensionAttribute3
Debug.Print " extensionAttribute4:", objUser.extensionAttribute4
Debug.Print " extensionAttribute5:", objUser.extensionAttribute5
Debug.Print " extensionAttribute6:", objUser.extensionAttribute6
Debug.Print " extensionAttribute7:", objUser.extensionAttribute7
Debug.Print " extensionAttribute8:", objUser.extensionAttribute8
Debug.Print " extensionAttribute9:", objUser.extensionAttribute9
Debug.Print " extensionAttribute10:", objUser.extensionAttribute10
Debug.Print " extensionAttribute11:", objUser.extensionAttribute11
Debug.Print " extensionAttribute12:", objUser.extensionAttribute12
Debug.Print " extensionAttribute13:", objUser.extensionAttribute13
Debug.Print " extensionAttribute14:", objUser.extensionAttribute14
Debug.Print " extensionAttribute15:", objUser.extensionAttribute15
Debug.Print "Protocol Setting:"
DescList = Null
Err.Clear
DescList = objUser.Get("protocolsettings")
If Err.Number <> -2147463155 Then
For Each Desc In DescList
i = InStr(1, Desc, "§", vbTextCompare)
If Left(Desc, i - 1) = "HTTP" Then
Desc = Right(Desc, Len(Desc) - i)
If Left(Desc, 1) = "1" Then
Debug.Print " HTTP: is enabled for mailbox"
Else
Debug.Print " HTTP: is not enabled for mailbox"
End If
Desc = Right(Desc, Len(Desc) - 2)
If Left(Desc, 1) = "1" Then
Debug.Print " HTTP: Use protocol defaults"
Else
Debug.Print " HTTP: Do not use protocol defaults"
End If
ElseIf Left(Desc, i - 1) = "IMAP4" Then
Desc = Right(Desc, Len(Desc) - i)
If Left(Desc, 1) = "1" Then
Debug.Print " IMAP4: is enabled for mailbox"
Else
Debug.Print " IMAP4: is not enabled for mailbox"
End If
Desc = Right(Desc, Len(Desc) - 2)
If Left(Desc, 1) = "1" Then
Debug.Print " IMAP4: Use server defaults"
Else
Debug.Print " IMAP4: Do not use server defaults"
End If
Debug.Print " IMAP4 MIME Encoding:"
Desc = Right(Desc, Len(Desc) - 2)
If Left(Desc, 1) = "0" Then
Debug.Print " Message should be MIME-encoded with both text and HTML body parts"
ElseIf Left(Desc, 1) = "1" Then
Debug.Print " Message should be MIME-encoded with text only body parts"
ElseIf Left(Desc, 1) = "4" Then
Debug.Print " Message should be MIME-encoded with HTML only body parts"
End If
Desc = Right(Desc, Len(Desc) - 2)
i = InStr(1, Desc, "§", vbTextCompare)
Debug.Print " Default Character set:", Left(Desc, i - 1)
'the last 4 values are not documented
'it is not supported to programmatically set these.

ElseIf Left(Desc, i - 1) = "POP3" Then
Desc = Right(Desc, Len(Desc) - i)
If Left(Desc, 1) = "1" Then
Debug.Print " POP3: is enabled for mailbox"
Else
Debug.Print " POP3: is not enabled for mailbox"
End If
Desc = Right(Desc, Len(Desc) - 2)
If Left(Desc, 1) = "1" Then
Debug.Print " POP3: Use server defaults"
Else
Debug.Print " POP3: Do not use protocol defaults"
End If
Debug.Print " POP3 MIME Encoding:"
Desc = Right(Desc, Len(Desc) - 2)
If Left(Desc, 1) = "0" Then
Debug.Print " Message should be MIME-encoded with both text and HTML body parts"
ElseIf Left(Desc, 1) = "1" Then
Debug.Print " Message should be MIME-encoded with text only body parts"
ElseIf Left(Desc, 1) = "2" Then
Debug.Print " POP3 UUencoding: Is Enabled "
Debug.Print " POP3 UUencoding: Use Binhex for macintosh is enabled"
ElseIf Left(Desc, 1) = "3" Then
Debug.Print " POP3 UUencoding: Is Enabled "
ElseIf Left(Desc, 1) = "4" Then
Debug.Print " Message should be MIME-encoded with HTML only body parts"
End If
Desc = Right(Desc, Len(Desc) - 2)
i = InStr(1, Desc, "§", vbTextCompare)
Debug.Print " Default Character set:", Left(Desc, i - 1)
i = InStr(1, Desc, "§", vbTextCompare)
Desc = Right(Desc, Len(Desc) - i)
If Left(Desc, 1) = "0" Then
Debug.Print " Use Rich Text is not enabled"
Else
Debug.Print " Use Rich Text is enabled"
End If
End If
Next
End If
mystring = "§"
i = Asc(mystring)
Debug.Print "ILS Settings"
i = InStr(1, objUser.autoReplyMessage, "/", vbTextCompare)
Debug.Print " ILS Server:", Left(objUser.autoReplyMessage, i - 1)
Debug.Print " ILS Account:", Right(objUser.autoReplyMessage, Len(objUser.autoReplyMessage) - i)

DescList = Null
Err.Clear
Debug.Print "Mailbox Rights"

' msExchMailboxSecurityDescriptoris a copy of what is in the MDB.
' It can not be modified programmatically.

objUser.GetInfoEx "msExchMailboxSecurityDescriptor", 0
Dim objsd As IADsSecurityDescriptor
Set objsd = objUser.Get("msExchMailboxSecurityDescriptor")
'----Enumerate an ACE in DACL----
Set dacl = objsd.DiscretionaryAcl
For Each ace In dacl

'----TRUSTEE----

mystring = ace.Trustee

'----ACE TYPE-----

If (ace.AceType = ADS_ACETYPE_ACCESS_ALLOWED) Then
mystring = " " & mystring & " is allowed:"
ElseIf (ace.Type = ADS_ACETYPE_ACCESS_DENIED) Then
mystring = " " & mystring & " is denied:"
End If

'----ACE MASK----

If (ace.AccessMask And RIGHT_DS_SEND_AS) Then
mystring = mystring & " -send mail as"
End If

If (ace.AccessMask And RIGHT_DS_CHANGE) Then
mystring = mystring & " -modify user attributes"
End If

If (ace.AccessMask And RIGHT_DS_DELETE) Then
mystring = mystring & " -delete mailbox store"
End If

If (ace.AccessMask And RIGHT_DS_READ) Then
mystring = mystring & " -read permissions"
End If
If (ace.AccessMask And RIGHT_DS_TAKE_OWNERSHIP) Then
mystring = mystring & " -take ownership of this object"
End If
If (ace.AccessMask And RIGHT_DS_MAILBOX_OWNER) Then
mystring = mystring & " -is mailbox owner of this object"
End If
If (ace.AccessMask And RIGHT_DS_PRIMARY_OWNER) Then
mystring = mystring & " -is mailbox Primary owner of this object"
End If

Debug.Print mystring

Next
RS.MoveNext
Wend
Set obj = Nothing
Set objUser = Nothing
Set dacl = Nothing
Set ace = Nothing

End If
Set oRootDSE = Nothing
Set oDomain = Nothing
Set oConnection = Nothing
Set oCommand = Nothing
Set RS = Nothing
Set RS2 = Nothing
End Sub

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Retrieving a Legacy Exchange Distinguished Name with ADSI

Visual Basic

' Retrieving legacy Exchange DN with ADSI
' In order to maintain compatiblity with previous versions of Exchange server a mail-enabled or mailbox-enabled
' object will store an Exchange distinguished name on that object in Active Directory.  This DN is used for
' replication using the Active Directory Connector (ADC) and should not be confused with the distinguished name for
' that object's location in Active Directory.

' This code can be run from any Windows 2000 or DSClient computer
Sub ExchangeDN()
Dim iAdCont As ActiveDs.IADs
Dim iAdGC As ActiveDs.IADs
Dim Conn As New ADODB.Connection
Dim Com As New ADODB.Command
Dim Rs As ADODB.Recordset
Dim varGCAdsPath As Variant
Dim strQuery As String
Dim strAlias As String

' change to the alias for the mailbox you are looking for
strAlias = "MyAlias"

' Get the Global Catalog
Set iAdCont = GetObject("GC:")
For Each iAdGC In iAdCont
   varGCAdsPath = iAdGC.ADsPath
Next

' Open the Connection
Conn.Provider = "ADsDSOObject"
Conn.Open "ADs Provider"

' Build the query to find the user based on his Alias
strQuery = "<" & varGCAdsPath & ">;(mailNickName=" & strAlias & ");name,distinguishedName,legacyExchangeDN;subtree"

Com.ActiveConnection = Conn
Com.CommandText = strQuery
Set Rs = Com.Execute

' Iterate through the results
While Not Rs.EOF
    MsgBox "The mailbox " & Rs.Fields("name") & " has an distinguished name of " & vbLf & _
            Rs.Fields("distinguishedName") & vbLf & " for Active Directory and " & vbLf & _
            Rs.Fields("legacyExchangeDN") & vbLf & " for previous versions of Exchange"
    Rs.MoveNext
Wend

'Clean Up
Rs.Close
Conn.Close
Set Rs = Nothing
Set Com = Nothing
Set Conn = Nothing
Set iAdCont = Nothing
Set iAdGC = Nothing
End Sub

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Finding the Exchange Organization Name Using ADSI

Visual Basic

'Finding the Exchange organization name using ADSI
'Find the Exchange organization name by searching Active Directory
'Can be run from any Windows 2000 or DSClient computer in the domain
'This sample requires a reference to the following libraries:
'Active DS Type Library (activeds.tlb)
'Microsoft ActiveX Data Objects 2.5 Library (msado15.tlb)

Sub main()

Dim iAdRootDSE As ActiveDs.IADs
Dim Conn As New ADODB.Connection
Dim Com As New ADODB.Command
Dim Rs As ADODB.Recordset
Dim varConfigNC As Variant
Dim strQuery As String

' Get the Configuration Naming Context
Set iAdRootDSE = GetObject("LDAP://RootDSE")
varConfigNC = iAdRootDSE.Get("configurationNamingContext")

' Open the Connection
Conn.Provider = "ADsDSOObject"
Conn.Open "ADs Provider"

' Build the query to find the organization
strQuery = "<LDAP://" & varConfigNC & ">;(objectCategory=msExchOrganizationContainer);name,cn,distinguishedName;subtree"

Com.ActiveConnection = Conn
Com.CommandText = strQuery
Set Rs = Com.Execute

' Iterate through the results
While Not Rs.EOF
' Output the name of the organization
MsgBox "The organization name is: " & Rs.Fields("cn")
Rs.MoveNext
Wend

'Clean Up
Rs.Close
Conn.Close
Set Rs = Nothing
Set Com = Nothing
Set Conn = Nothing

End Sub

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Finding the Exchange Organization Name Using ADSI

When compiling the following example, you must also link with activeds.lib and adsiid.lib.

Visual C++

//Find the Exchange Organization name using ADSI
//Find the Exchange organization name by searching Active Directory
//Can be run from any DSClient enabled computer

#include <activeds.h>
#include <stdio.h>

void main()
{
  CoInitialize(NULL);
   HRESULT hr = S_OK;
   //Get rootDSE and the configuation container's DN.
   IADs *pADs = NULL;
   IDirectorySearch *pDirSrch = NULL;
   LPOLESTR szPath = new OLECHAR[MAX_PATH];
   VARIANT var;
   hr = ADsOpenObject(L"LDAP://rootDSE",
      NULL,
      NULL,
      ADS_SECURE_AUTHENTICATION, //Use Secure Authentication
      IID_IADs,
      (void**)&pADs);
   if (FAILED(hr))
   {
      wprintf(L"Not Found. Could not bind to the domain.\n");
      if (pADs)
         pADs->Release();
      return;
   }

   hr = pADs->Get(L"configurationNamingContext",&var);
   if (SUCCEEDED(hr))
   {
      wcscpy(szPath,L"LDAP://");
      wcscat(szPath,var.bstrVal);
      VariantClear(&var);

      //Bind to the root of the configuation context
      hr = ADsOpenObject(szPath,
         NULL,
         NULL,
         ADS_SECURE_AUTHENTICATION, //Use Secure Authentication
         IID_IDirectorySearch,
         (void**)&pDirSrch);
      if (SUCCEEDED(hr))
      {
         HRESULT hr = E_FAIL;
         //Create search filter
         LPOLESTR pszSearchFilter = new OLECHAR[MAX_PATH];
         LPOLESTR szADsPath = new OLECHAR[MAX_PATH];
         wcscpy(pszSearchFilter, L"(objectCategory=msExchOrganizationContainer)");
         //Search entire subtree from root.
         ADS_SEARCHPREF_INFO pSearchPrefs;
         pSearchPrefs.dwSearchPref = ADS_SEARCHPREF_SEARCH_SCOPE;
         pSearchPrefs.vValue.dwType = ADSTYPE_INTEGER;
         pSearchPrefs.vValue.Integer = ADS_SCOPE_SUBTREE;
         DWORD dwNumPrefs = 1;
         // COL for iterations
         ADS_SEARCH_COLUMN col;
         // Handle used for searching
         ADS_SEARCH_HANDLE hSearch;
         // Set the search preference
         hr = pDirSrch->SetSearchPreference( &pSearchPrefs, dwNumPrefs);
         if (FAILED(hr))
            return;
         // Set attributes to return
         CONST DWORD dwAttrNameSize = 1;
         LPOLESTR pszAttribute[dwAttrNameSize] = {L"cn"};

         // Execute the search
         hr = pDirSrch->ExecuteSearch(pszSearchFilter,
            pszAttribute,
            dwAttrNameSize,
            &hSearch
            );
         if (SUCCEEDED(hr))
         {

            // Call IDirectorySearch::GetNextRow() to retrieve the next row of data
            while( pDirSrch->GetNextRow( hSearch) != S_ADS_NOMORE_ROWS )
            {
               // loop through the array of passed column names,
               // print the data for each column
               for (DWORD x = 0; x < dwAttrNameSize; x++)
               {
                  // Get the data for this column
                  hr = pDirSrch->GetColumn( hSearch, pszAttribute[x], &col );
                  if ( SUCCEEDED(hr) )
                  {
                     wprintf(L"Organization name is: %s\n",col.pADsValues->CaseIgnoreString);
                  }
                  pDirSrch->FreeColumn( &col );
               }
            }
         }
         // Close the search handle to clean up
         pDirSrch->CloseSearchHandle(hSearch);
      }
   }
   if (pADs)
   {
      pADs->Release();
      pADs = NULL;
   }
   if (pDirSrch)
   {
      pDirSrch->Release();
      pDirSrch = NULL;
   }
  CoUninitialize();
}

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Finding Exchange AddressLists with ADSI

Visual Basic

'Finding Exchange AddressLists with ADSI
'This sample finds Exchange addresslists by searching the Active Directory

'Add a reference to ADO 2.5 libraries (msado15.dll)
'Add a reference to Active DS Type Library (Activeds.tlb)

Sub AddressList()
    'Find the Exchange addresslists by searching the Active Directory
    'Can be run from any DSClient enabled computer

    Dim iAdRootDSE As IADs
    Dim Conn As New ADODB.Connection
    Dim Com As New ADODB.Command
    Dim Rs As ADODB.Recordset
    Dim varConfigNC As Variant
    Dim strQuery As String

    ' Get the Configuration Naming Context
    Set iAdRootDSE = GetObject("LDAP://RootDSE")
    varConfigNC = iAdRootDSE.Get("configurationNamingContext")

    ' Open the Connection
    Conn.Provider = "ADsDSOObject"
    Conn.Open "ADs Provider"

    ' Build the query to find all the AddressLists
    strQuery = "<LDAP://" & varConfigNC & ">;(objectCategory=addressBookContainer);name,purportedSearch;subtree"

    Com.ActiveConnection = Conn
    Com.CommandText = strQuery
    Set Rs = Com.Execute

    ' Iterate through the results
    While Not Rs.EOF
        ' Output the name of the address list and the query that is used to build it
        Debug.Print "Name: " & Rs.Fields("name") & vbLf & "Query: " & Rs.Fields("purportedSearch")
        Rs.MoveNext
    Wend

    'Clean Up
    Rs.Close
    Conn.Close
    Set Rs = Nothing
    Set Com = Nothing
    Set Conn = Nothing

End Sub

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Creating a Distribution List Using CDOEXM and ADSI

Visual Basic

'Creating a distribution list using CDOEXM and ADSI
'This sample creates a distribution list in a given AD container. It uses a slightly modified version of the Platform SDK code to create a group, and then mail-enables the group using CDOEXM

'A distribution list in Exchange 2000 is a normal Windows 2000 group, either security or non-security
'which has been mail-enabled.  This sample uses the function CreateDL to create the
'distribution list and CDOEXM to mail-enable it.

Function CreateDL(strPath As String, strGroupName As String, strSamAcctName As String, strGroupType As String, bSecurity As Boolean) As IADsGroup
' =========================================================
'CreateDL(strPath As String, strGroupName As String, strSamAcctName As String, strGroupType As String, bSecurity As Boolean)
'   strPath = ADsPath of the Container under which the group will be created
'   strGroupName = Name of the Group to be Created
'   strSamAcctName = Group name as it will appear to pre-Windows2000 machines
'   strGroupType = Type of group to be created(Local,Domain Local, Global, or Universal)
'   bSecurity = Is this a security group?

'  Function returns an IADsGroup object

' Example of calling the function:
' Set objNewGroup = CreateDL("LDAP://cn=Users,dc=corp,dc=com", "My New Group", "NewGroup", "Global", False)
'  Then add users
'  objNewGroup.Add strUser1ADsPath
'  objNewGroup.Add strUser2ADsPath
' =========================================================

 Dim lGroupType As Long
 Dim iAdCont As IADsContainer
 Dim iAdGroup As IADsGroup
 Dim iMailRecip As IMailRecipient

 '  --- Set the type of Group ------
 lGroupType = 0
 Select Case UCase(strGroupType)
 Case "LOCAL": lGroupType = ADS_GROUP_TYPE_LOCAL_GROUP
 Case "DOMAIN LOCAL": lGroupType = ADS_GROUP_TYPE_DOMAIN_LOCAL_GROUP
 Case "GLOBAL": lGroupType = ADS_GROUP_TYPE_GLOBAL_GROUP
 Case "UNIVERSAL": lGroupType = ADS_GROUP_TYPE_UNIVERSAL_GROUP
 Case Else
    Debug.Print "This is not a proper group type"
    Exit Function
 End Select

 ' ----  Check to see if it is a Security Group ----
 If bSecurity Then
   lGroupType = lGroupType Or ADS_GROUP_TYPE_SECURITY_ENABLED
 End If

 ' ---- Create the Group ----
 Set iAdCont = GetObject(strPath)
 Set iAdGroup = iAdCont.Create("group", "cn=" + strGroupName)
 iAdGroup.Put "sAMAccountName", strSamAcctName
 iAdGroup.Put "groupType", lGroupType
 iAdGroup.SetInfo         'flush to the directory

 '--- Mail Enable ----
 Set iMailRecip = iAdGroup
 iMailRecip.MailEnable

' Write Exchange information to the directory
 iAdGroup.SetInfo

 'Return group
 Set CreateDL = iAdGroup

 'CleanUp
 Set iMailRecip = Nothing
 Set iAdGroup = Nothing
 Set iAdCont = Nothing
End Function

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Setting Message Restriction on an SMTP Virtual Server Using ADSI

Visual Basic

'Set message restriction on SMTP Virtual Server using ADSI
'This sample will set the message restriction for all of the virtual
'SMTP servers in an administrative group in an organization. In order
'to simplify the sample you must set the value of strOrg to an Organization
'Name and set the value of strAdmiGrp to an administrative group
'By default a Platinum server will have an administrative group
'called First Administrative Group.

Sub SetMsgRestriction()
Dim oRootDSE As IADs
Dim oConnection As New ADODB.Connection
Dim oCommand As New ADODB.Command
Dim oRecordSet As ADODB.Recordset
Dim oRecordSet2 As ADODB.Recordset
Dim varConfigNC As Variant
Dim strQuery As String
Dim strOrg As String
Dim strAdminGrp As String

On Error Resume Next

'TODO: set these next two variables
strOrg = "Microsoft"
strAdminGrp = "First Administrative Group"

' Get the Configuration Naming Context
Set oRootDSE = GetObject("LDAP://RootDSE")
varConfigNC = oRootDSE.Get("configurationNamingContext")

' Open the Connection
oConnection.Provider = "ADsDSOObject"
oConnection.Open "ADs Provider"
oCommand.ActiveConnection = oConnection
oCommand.Properties("Page Size") = 99

strQuery = "<LDAP://CN=Servers,CN=" & _
            strAdminGrp & ",CN=Administrative Groups,CN=" & _
            strOrg & ",CN=Microsoft Exchange,CN=Services," & _
            varConfigNC & _
            ">;(objectCategory=msExchExchangeServer);distinguishedname;subtree"

oCommand.CommandText = strQuery
'Get a Record set of all the servers
Set oRecordSet = oCommand.Execute
'Iterate through the Servers
'check for errors
If Err.Number = 0 Then
    While Not oRecordSet.EOF
    ' Build the query to find all Virtual SMTP Servers on each Server in the strAdminGroup
        Err.Number = 0
            strQuery = "<LDAP://cn=SMTP,cn=Protocols," _
                    & oRecordSet("distinguishedname").Value & _
                    ">;(|(objectCategory=protocolCfgSharedServer)(objectCategory=protocolCfgSMTPServer));distinguishedname;subtree"
            Debug.Print strQuery
            oCommand.ActiveConnection = oConnection
            'reset the error to null so we can check it later.
            Err.Number = 0
            oCommand.CommandText = strQuery
            Set oRecordSet2 = oCommand.Execute
        'if a recordset was returned.....
            If Err.Number = 0 Then
        'Iterate through the Virtual SMTP Servers
                While Not oRecordSet2.EOF
                   ADsPath = "LDAP://" & oRecordSet2("distinguishedname").Value
                   Set oSMTP = GetObject(ADsPath)
                   Debug.Print oSMTP.msExchSmtpMaxMessageSize
                    'set the Maximume Message size to 5000 KB or 5120000 bytes
                    oSMTP.Put "msExchSmtpMaxMessageSize", 5120000
                    oSMTP.SetInfo
                    ' other properties of interest :
                    'msExchSmtpMaxMessageSize - Limit message size to (KB)
                    'msExchSmtpMaxSessionSize - Limit session to (KB)
                    'msExchSmtpMaxOutboundMsgPerDomain  - Limit messages per connection
                    'msExchSmtpMaxRecipients - Limit number of recipient per message
                    'msExchSmtpSendNDRTo - Send copy of Non-Delivery report to
                    'msExchSmtpQueueDirectory - BadmailDirectory
                    'msExchAlternateServer - Forward all mail with unresolved recipients to host.
                    'msExchMaxIncomingConnections - Limit number of connection to
                    'msExchServerBindings  IP Address
                    'msExchServerBindingTurflist Enable Filter Turf List
                    'msExchIncomingConnectionTimeout - Connection time-out (minutes)
                    'msExchLogType - Enable Logging
                    'msExchAuthenticationFlags - Access Control
                    'msExchIPSecurity - Connection control
                    'msExchSMTPRelayIpList - Relay IP restictions list
                    'msExchSmtpRemoteQueueRetries - Delivery Outbound retries
                    'msExchSmtpRemoteQueueDelayNotification - Delivery outbound delay notification
                    'msExchSmtpRemoteQueueExpirationTimeout - Delivery outbound expiration timeout
                    'msExchSmtpLocalQueueDelayNotification - Delivery Local delay notification
                    'msExchSmtpRemoteQueueExpirationTimeout - Delivery Local expiration timeout

                     oRecordSet2.MoveNext
                Wend
                oRecordSet2.Close
        End If
        oRecordSet.MoveNext
    Wend
Else
    Debug.Print "Bad information for strOrg = " & strOrg & " or for strAdminGrp =" & strAdminGrp
End If
'Clean Up
oRecordSet.Close
oConnection.Close

Set oRecordSet = Nothing
Set oRecordSet2 = Nothing
Set oCommand = Nothing
Set oConnection = Nothing

End Sub

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Building Web Storage System Forms

Microsoft® Exchange 2000 Server provides the environment for the Web Storage System Forms technology that represents a data-focused approach to building Web applications for Exchange. This section describes how you can create Web-based access to Exchange 2000 Server data using Web Storage System Forms and Microsoft® Outlook® Web Access views.

For more information about building Web-based access to Exchange 2000 Server data using Web Storage System Forms, see the following sections:

Introduction

Before You Start

Concepts and Architecture

Programming Tasks

Example Code

Related Topics

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Introduction

Microsoft Web Storage System Forms is a Web-based forms technology that is built on Internet standards. A Web Storage System form is a Web page that is registered in the Forms Registry of the Web Storage System. Registering a form in the Forms Registry allows Active Server Pages (ASP) and HTML pages to be associated with a specific type of data in the Web Storage System and to replace the default Microsoft® Outlook® Web Access rendering when an HTTP request for the data is made.

The registration entry in the Forms Registry specifies the rendering engine for the form. This makes it possible to override the default Outlook Web Access rendering and envoke a custom ASP script and HTML, which allows you to provide the presentation and data content your application requires.

The registration itself is a single record in the Web Storage System store. Each registration entry contains a set of properties for the item or folder that the request is made against and for the user's browser and environment. The form registration properties include a property, the executeurl, that specifies the URL of the engine that renders the form and another, the formurl, that lists the name of the Web Storage System or ASP file that displays the Web page. Form Definition Properties describes the collection of form definition properties for a form registration.

Web Storage System forms can by rendered by two different engines. Exchange provides the Forms Renderer, an Internet Server Application Programming Interface (ISAPI) DLL extension named exwforms.dll, or you can write an ASP script and use it to render the Web form. An ASP script or an HTML file can provide the markup language that renders the Web form. The Forms Renderer can process both file types, and you can use the language and technology that best suits your needs. Using the ASP technology offers the advantage of support for data validation and other business logic.

For more information about the concepts and architecture of Web Storage System Forms, see the following sections:

Overview of Web Storage System Forms

Web Storage System Form Registration

For more information about the programming tasks associated with building Web Storage System Forms, see the following section:

Registering a Web Storage System Form

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Before You Start

This section contains topics that specifically describe the requirements for setting up the development environment and the tools for developing Microsoft Web Storage System Forms.

For more information about for working with Microsoft® FrontPage® Extensions, see the following section:

About Microsoft FrontPage Extensions for Web Storage System Forms

Development Environment provides general information about how to set up an environment for developing applications for Microsoft® Exchange 2000 Server.

Additional information will be provided here as it becomes available.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


About Microsoft FrontPage Extensions for Web Storage System Forms

Microsoft® FrontPage® Extensions for Web Storage System Forms enables you to create Web Storage System Forms using FrontPage 2000.

The FrontPage Extensions for Web Storage System Forms uses an installation wizard.

A standard installation includes the following components:

  • FrontPage 2000 Component Object Model (COM) add-in.
  • Microsoft® Exchange 2000 Server field chooser.
  • Design time controls.
  • Form registration tool.
  • A wizard for creating a Web Storage System Web site.
Note Web Storage System Forms for Exchange 2000 Server must be installed prior to installing FrontPage Extensions.

The following tasks can be performed in any order:

  • Configure FrontPage Server Extensions and add users to the FrontPage Administrators group.
  • Install FrontPage 2000.
  • Install FrontPage Extensions for Web Storage System Forms.

Hard Disk Requirements

The FrontPage Extensions requires 2 MB of free space.

Software Requirements

There are different software requirements depending on the use of Web Storage System Forms.

User Machine

To view Web Storage System Forms, the user's machine needs a HTML 3.2-capable web browser. Microsoft® Internet Explorer 5 or later is recommended to take advantage of the Web Storage System Forms complete functionality.

Authoring Machine

To author/create Web Storage System Forms, authoring machines require the following:

  • Web Storage System Forms for Exchange 2000 Server.
  • FrontPage 2000.
  • Internet Explorer 5 or later is required to author and view Dynamic HTML (DHTML) behaviors.

Server Machine

To host Web Storage System Forms, the server machine requires the following:

  • Microsoft® Windows® 2000 Server or Advanced Server.
  • Exchange 2000 Server.
  • Microsoft FrontPage Server Extensions must be enabled.
Note If FrontPage has not been installed on the server, some of the necessary groups will not be created. The groups are: servernname Admins, servername Authors, and servername browsers. The users are fpadmin, fpauthor, and fpbrowser.

Adding FrontPage users to the server

To add FrontPage users, ensure that groups and users do not already exist. At the command prompt, type "net localgroup".

Populating FrontPage groups

If FrontPage Server Extensions have been configured, the groups exist but may not be populated. By default, FrontPage adds the built-in Administrators group to the "%computername% Admins" group.

To create the groups and users, create the following file. To execute the file, open a command prompt and run the file.

Create.bat

rem Create 3 local groups for FrontPage
net localgroup "%computername% Admins" /add
net localgroup "%computername% Authors" /add
net localgroup "%computername% Users" /add
rem Create 3 users - password for each is "password"
net user fpadmin password /add
net user fpauthor password /add
net user fpbrowser password /add
rem Add each user to the corresponding group
net localgroup "%computername% Admins" fpadmin /add
net localgroup "%computername% Authors" fpauthor /add
net localgroup "%computername% Browsers" fpbrowser /add

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Installing FrontPage Extensions for Web Storage System Forms

For the recommended installation of Microsoft® FrontPage® Extensions:

  • Double-click the FrontPage_Client.msi file and follow the installation wizard.
Note Web Storage System Forms must be installed prior to installing FrontPage Extensions.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Enabling FrontPage Server Extensions

To use the Microsoft® FrontPage® Server Extensions for Web Storage System Forms, FrontPage Server Extensions must be enabled.

To enable FrontPage Server Extensions:

  1. From the Start button, click Administrative Tools, and then click Internet Services Manager.
  2. Select the default Web site.
  3. Right-click the public Web and click Server Extensions Web from the New menu.
  4. Use the New Subweb Wizard and provide the directory name and title for the new Subweb.
  5. Assign an administrator Subweb.
  6. Click Finish to create the new Subweb.

For more information about installing and configuring server extensions and adding appropriate user permissions for creating FrontPage 2000 Web pages, see the FrontPage Server Extensions documentation.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Concepts and Architecture

The topics in this section describe the architecture of, and illustrate key concepts for, building Web Storage System Forms. The Overview topic includes a diagram that illustrates the Web Storage System Form process, and describes the steps in the process.

For more information about the concepts, architecture, and general programming principles for Web Storage System Forms, see the following sections:

Overview of Web Storage System Forms

Web Storage System Form Registration

Reusing Elements of Outlook Web Access

Creating Web Storage System Forms Using FrontPage Extensions

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Overview of Web Storage System Forms

A Web Storage System Form is a Web page that is registered in the Web Storage System. Web Storage System Forms consist of the following pieces:

  • Form registration
  • Forms Renderer
  • Microsoft® Internet Explorer 5 Dynamic HTML (DHTML) views and behaviors

Understanding the Web Storage System Form Process

The following diagram illustrates the Web Storage System Form process. The numbered items show the steps of the process and are explained below.

  1. The user requests information from a computer running Microsoft® Exchange 2000 Server by opening a folder or a message. This request is processed by Microsoft Internet Information Services (IIS).
  2. IIS invokes an Internet Server Application Programming Interface (ISAPI) dynamic-link library (DLL), the same DLL that the Web Storage System uses to process all World Wide Web Distributed Authoring and Versioning (WebDAV) requests. The ISAPI.dll checks the Web Storage System Forms registry to see if a matching Web Storage System Form registration exists.
  3. A form registration is an item in the Web Storage System that consists of a series of form definition fields. These fields specify properties to be matched, such as browser type and language, and processing information. These fields specify which form to render and how to render the form. Information read from the HTTP request header is processed and compared against browser information that is stored in the Browsecap.ini file to determine browser capabilities. The ISAPI.dll uses a best-fit comparison with the forms registry to determine the form to display to the user.

    If a matching form registration is found, then the computer checks the form registration to see how to render the form. If a matching registration does not exist, then the requested information is rendered with a standard form.

  4. The Forms Registry passes two parameters to the Forms Renderer.
    • formurl - Value in formurl the parameter.
  5. A Web Storage System Form can be rendered in three ways:
    • As a custom Active Server Pages (ASP) page.
    • As an HTML page using the Forms Renderer.
    • As an ASP page using the Forms Renderer.

    At this point, data items are bound to the form. Data items can be message, contacts, calendaring, custom properties, and so forth.

  6. The Forms Renderer returns the form and form data to IIS.
  7. IIS returns the Web page to the requesting Web browser. Depending on the capabilities of the Web browser, data is bound on the server or the client.

Related Topics

  • Web Storage System Form Registration
  • Form Definition Properties

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Web Storage System Form Registration

The Web Storage System Form registration links the custom Web Storage System Forms and the data items. Data items can be messages, contacts, calendaring, custom properties, and so forth.

A form registration is an item in the Web Storage System that consists of a series of form definition fields. Usually there is a single form registration for each Web Storage System Form. However, multiple form registrations can exist for a Web Storage System Form. For example, you might want to show the same form as the default form for the directory and another form to edit an existing item or to create a new item.

These fields specify properties that are matched. Properties include the browser type, language, processing information, and which form to render.

A Web Storage System Form registration determines when Microsoft® Exchange 2000 Server displays a custom form. For example, the form can be displayed as the default view for a folder, the response to a command such as Open or Edit, or it can be displayed when the user opens an item of a particular content class.

The following topics are covered:

Web Storage System Forms Registry

Schema Collection Reference

Form Definition Properties

Order of Precedence for Form Definition Properties

Default Form Registration

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Web Storage System Forms Registry

The Web Storage System Forms Registry provides a method of storing form registrations in the Web Storage System. The registration can specify customized forms and actions based on a set of properties. This provides a way to register and query forms that are associated with an item of a particular content class.

Form registrations are stored in the Web Storage System, similar to the way schema and event registrations are stored. For more information about schema or event registrations, see the Microsoft® Exchange 2000 Server SDK documentation.

Form registrations can be saved with forms and this makes it easier to manage the application. For example, in an expense tracking application, you can create a schema subfolder and store the registration and schema information for that application in the same schema folder.

Forms and Form Definitions are stored in the same location. Properties in the form registrations can use either absolute or relative URLs.

Note The Web Storage System Forms Registry is a new technology. It is not the Microsoft® Windows® registry or the Component Object Model (COM) registry.

Absolute or Relative Registration

Forms can be registered with an absolute or relative reference to the registration item. Relative references are relative to the location of the form. Absolute references utilize the entire URL. The following is an example of relative and absolute registration formats that the Form URL can take:

  • /forms/form.htm. A relative URL, relative to the form registration.
  • /public/webapps/app/forms/form.htm. This is relative to the virtual server from the HTTP request.
  • <http://server/public/webapps/app/forms/form.htm>. No processing happens in the rendering engine, and the form is passed to the executeUrl method unchanged.
Note Although absolute registration is supported, it is not recommended because relative registrations are much easier to maintain.

Configuration Notes

Data and forms must be stored on a single server. Users should only access the Web application on a server where it physically resides. If the data is on one server, but the form is on another server, the Forms Renderer is unable to access what it needs.

To have a distributed setup, full public folder replication must be activated for the Web application.

Registrations and Security

To register a form in a Web Storage System folder, you must have permissions to modify items in that folder.

Security is based on the Windows 2000 and Microsoft® Windows NT® security model and on the security identifiers (SIDs) of users. Discretionary access control lists (ACLs) can be set on any item in the Web Storage System.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Schema Collection Reference

Objects in the Web Storage System define the location of their schema through the Schema Collection Reference (SCR). This property is urn:schemas-microsoft-com:exch-data:schema-collection-ref. The SCR is a URL that indicates a folder in the Web Storage System. The SCR is the starting location used to search for the schema information of the application.

The SCR can point to the current folder or to another folder that contains schema information. The default starting location is non_ipm_subtree/schema folder unless the SCR is set. The SCR is set through a Web Storage System form registration.

An example of such a URL is http://servername.microsoft.com/public/myschema.

The urn:schemas-microsoft-com:exch-data:baseschema property is a multivalued string that defines the URLs to search for schema information. A multivalued string is different from the SCR because the baseschema property contains all of the locations that are searched. The SCR specifies where to start the search.

Note Because there is no HTTP proxy between Microsoft® Exchange servers, the SCR must point to a folder in the Web Storage System where the object exists.

For more information about searching schemas, see "Schema Scope" in the Exchange 2000 Server SDK.

XML Namespaces

An XML namespace is a label that accompanies a set of elements or attributes. The namespace uniquely identifies these elements or attributes by limiting the scope.

Namespace Examples
<xmlns:d="DAV:"
xmlns:f="urn:schemas-microsoft-com:office:forms"
xmlns:c="urn:schemas:calendar:">

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Form Definition Properties

A form registration consists of a collection of form definition properties. The properties define other properties such as the browser version, information about data binding, and information about events performed on an object. The content class property is required and all other form definition properties are optional. The most basic form registration can consist of the following properties:

  • The content class of the form registration
  • The content class of the form
  • The URL of the form
  • The executeurl

Syntax

Property name = item

urn:schemas-microsoft-com:office:forms#browser = "Microsoft Internet Explorer

Property List

Property name | Description
urn:schemas-microsoft-com:office:forms#binding | Case-insensitive. Indicates the binding type. Possible values are server, client, and Web-client.
urn:schemas-microsoft-com:office:forms#browser | Case-insensitive. Indicates the type of browser. An asterisk (*) indicates a wildcard. Example: urn:schemas-microsoft-com:office:forms#browser = Microsoft® Internet Explorer
urn:schemas-microsoft-com:office:forms#cmd | Case-insensitive. String denoting the action or behavior being performed on an object. This is the first parameter after the command (?cmd= of the URL returned from Microsoft Internet Information Services (IIS) roughly corresponding to the Internet Server Application Programming Interface (ISAPI) QUERY_STRING.) The QUERY_STRING is delimited by ampersands (&) that represent modifiers of the action. Example: urn:schemas-microsoft-com:office:forms#cmd = NewArt
urn:schemas-microsoft-com:office:forms#contentclass | Case-insensitive. Associated with a set of schemas and a set of forms. The content class for which the form is registered. Example: urn:schemas-microsoft-com:office:forms#contentclass = urn:content-classes:message
urn:schemas:microsoft-com:office:forms#contentstate | Case-insensitive. http://schemas.microsoft.com/exchange/contents Example: urn:schemas:microsoft-com:office:forms#contentstate = "mySample"
urn:schemas-microsoft-com:office:forms#executeparameters | Parameters that are passed to the rendering engine specified by the executeurl property. The parameters must be URL escaped. An ampersand (&) is used to separate multiple values. Example: param1=mySample& m2=url%20escaped
urn:schemas-microsoft-com:office:forms#executeurl | The URL to execute to render a form. An ISAPI filter or Active Server Pages (ASP) page. Example: process.asp
urn:schemas-microsoft-com:office:forms#formurl | The URL of the form or template being handled and rendered, the item that is denoted by the current URL. Example: ExpenseForm.htm
urn:schemas-microsoft-com:office:forms#language | Automatically provided as part of the HTTP request headers, this is the language of the form. This attribute corresponds to a case-insensitive ISO language-country/region value in the Accept-Language HTTP header. Example: en
urn:schemas-microsoft-com:office:forms#majorver | Indicates the major version of the browser. Example: <5
urn:schemas-microsoft-com:office:forms#messagestate | Case-insensitive. Values include normal, submitted, read, unread, and importance. Status of the item.
urn:schemas-microsoft-com:office:forms#minorver | The minor version of the browser. Example: =5
urn:schemas-microsoft-com:office:forms#platform | Case-insensitive. The platform of the browser matched against forms registrations. The platform information is in the same format as it is in browscap.ini. Example: Microsoft Windows NT
urn:schemas-microsoft-com:office:forms#request | Case-insensitive. Property used to specify whether the form uses GET or POST requests. There are two possible values: GET and POST. GET queries for information, POST writes information. Examples: GET, POST
urn:schemas-microsoft-com:office:forms#version | Value includes a relational operator. Example: >5

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Order of Precedence for Form Definition Properties

To prevent conflicting values, a specific order of preference is used to determine which property takes precedence when the form registration is read.

A non-wildcard value has the highest precedence, a wildcard value has middle precedence, and a null value has lowest precedence. Attributes must match exactly, except for browser capability.

The registry uses the following order of precedence:

  1. HTTP request
  2. URL action (cmd)
  3. Message-State
  4. Content-State
  5. Browser capability (browser type and version)
  6. Version
  7. Platform
  8. MajorVer
  9. MinorVer
  10. Language

For the version properties, the precedence order (highest to lowest) is =, <=, >=, <, >, *, and then null.

Browser capability comparisons are as follows:

= equals

<= less than or equal to

>= greater than or equal to

< less than

> greater than

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Default Form Registration

A Web Storage System Form can be registered as the default form. This action replaces the general default form registration used by Microsoft® Outlook® Web Access that lists of the contents of the folder.

To register a Web Storage System Form as the default form, perform the following steps:

  1. Create the form.
  2. Set the urn:schemas-microsoft-com:exch-data:schema-collection-ref property.
  3. Create a form registration for the content class of urn:content-classes:folder.
  4. Set CMD="*" and Request="GET" in the form registration. The * is a wildcard.
Note Registering a form overrides the setting in the DAV:defaultdocument property.

To register a Web Storage System Form as the default form for new items:

  1. Create a form registration for http://server/appvroot?cmd=new.
  2. Pass in flags to the Forms Renderer by way of the Forms Registry to tell the Forms Renderer to create a new item when it is posted.
  3. Save the form. The item is not created until the form is saved.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Comparing Formurl and Executeurl

The form registration specifies the executeurl and the formurl properties for a Web form. The executerurl property specifies the URL of the engine that renders the form. The request is directed to this URL. The formurl property passes the query string on to the URL specified in the executeurl.

The rendering can be performed by an ASP page or an ISAPI filter. The following two lines of code show the implementation of these rendering mechanisms.

Specify an ISAPI Filter in executeurl

<form:executerurl>/exchweb/bin/excwform.dll</form:executeurl>

Specify an ASP Page in executeurl

<form:executerurl>ASP1.asp</form:executeurl>

The formurl is the URL of a form or a template. The following line of code shows how an HTML file, named Page1.htm, is specified in the formurl.

Specify an HTML Page in formurl

<form:formurl>Page1.htm</form:formurl>

The executeurl is always required, but there are circumstances under which you do not need to specify the formurl. When the executeurl and the formurl point to the same ASP page, you do not need to include the formurl. However, it customary to include both entries, repeating the ASP entry.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Reusing Elements of Outlook Web Access

Developers can create customized Web pages by reusing pieces of Microsoft® Outlook® Web Access. These pieces can be embedded in a Web page. Tables, Frames, and IFrames can be used to arrange the Outlook Web Access pieces.

For example, a Web page could contain the user’s inbox and the group calendar. It could have a brand or company identifier in one corner and current news and links to internal tools in another corner.

For more information about embedding pieces of Outlook Web Access in a Web page, see the following sections:

Working with Default Views

Controlling the Navigation Bar

URL Parameters

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Working with Default Views

Microsoft® Outlook® Web Access provides default views for everyday tasks — for example, viewing an inbox or outbox. Default views can be manipulated by specifying additional parameters.

The syntax for adding parameters is:

http://"ServerName"/"exchange"/"UserName"/parameter

For example, if you want to see the deleted items for a user named "User1" on a server named Finance, you type the following URL:

http://"Finance"/"exchange"/"User1"/deleted%20items

Parameter names include Inbox, Outbox, Calendar, Contacts, Deleted Items, Drafts, and Sent Items.

Note Spaces in names are represented with the characters %20.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Controlling the Navigation Bar

The Outlook bar normally appears in a frame on the left side of the browser window. The Outlook bar allows the user to navigate between different views, such as Inbox and Outbox.

However, you may want to display the Microsoft® Outlook® Web Access contents in the browser window without the Outlook bar. You can do this by adding ?Cmd=contents to the URL.

You can display just the navigation bar by adding ?Cmd=navbar to the URL.

The code in the following example shows the contents of the inbox without the navigation bar:

http://servername/exchange/user1/inbox/?Cmd=contents

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


URL Parameters

URL parameters can be used to show calendar views, view open messages, and perform other tasks in the browser window. The parameters can be broken into two categories: commands and options. Commands handle information. Options control how the information is viewed.

Commands - New, Get, Post, Reply, Forward, Save, Send

Parameter name | Description
Post | Defines how data is submitted to the server.
Get | Defines how data is requested from the server.
New | Creates a new item.
Reply | Replies to a message.
Forward | Forwards a message.
Save | Saves a message.
Send | Sends a message.

Options - Date, Page, Sort, View

Parameter name | Description
Page=x | Displays page x.
View=x | Displays Outlook view named x.
Sort=x | Sorts by column x.
Date=x | Displays date in calendar.

Cmd Examples

The syntax for the cmd parameter is "http://server_name/Exchange_v-root/folder/item_name ?Cmd=action[&modifier [&modifier]]".

To do this | Use this syntax (examples)
View an Existing Object | http://server_name/v-root/folder/item_name?Cmd=action
Create a New Message | http:// server_name/v-root /user_name/Drafts/?Cmd=new
View or Change Options | http://ServerName/exchange/UserName/?Cmd=options
Open a Message in the User's Inbox | http://server_name/exchange_v-root/folder/inbox/messagename.EML?Cmd=open Messagename is the subject that the sender types. It is also the file name in the folder.
View a Calendar by Month or by Week | http://server_name/v-root/user_name/calendar/?Cmd=contents&View=Monthly http://server_name/v-root/user_name/calendar/?Cmd=contents&View>=Weekly&Date=11/09/1999

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Creating Web Storage System Forms Using FrontPage Extensions

This section includes topics about creating Microsoft Web Storage System Forms using Microsoft® FrontPage® Extensions. This section also covers registering forms with the Web Storage System.

Creating a Basic Web Storage System Form

Customizing a Web Storage System Form

FrontPage Extensions Components

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Creating a Basic Web Storage System Form

Microsoft® FrontPage® Extensions for Web Storage System Forms provide two ways to create a basic Web Storage System Web site.

One method is to create a regular FrontPage Web page and fill in the Form Properties dialog box under the WSSForms menu. Another method is to use the Web Storage System Forms wizard. This section covers both of these methods.

Using Form Properties on a FrontPage Web Page

Creating a Basic Exchange 2000 Web Application

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Using Form Properties on a FrontPage Web Page

A Web Storage System Form can be added to a regular Microsoft® FrontPage® Web by registering the form with the Forms Registry.

  1. Create a standard FrontPage Subweb in the Exchange 2000 Server public folder.
  2. In FrontPage 2000, select Form Properties from the WSSForms menu.
  3. Use the default selections to register the form in the Forms Registry.

Related Topics

  • FrontPage Extensions Components

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Creating a Basic Exchange 2000 Web Application

Microsoft® FrontPage® Extensions provide a basic Microsoft® Exchange 2000 Web wizard for creating a Web application. Forms created using the wizard can be customized with the exact properties required by the user. The wizard ensures that all of the correct entities are provided for the application.

The wizard performs the following tasks:

  • Sets the urn:schemas-microsoft-com:exch-data:expected-content-class property for folders where data will be stored
  • Creates a Schema folder
  • Places the form and view
  • Creates form registrations for the default view
  • Sets the default document properties for the root application folder
  • Sets the urn:schemas-microsoft-com:exch-data:schema-collection-ref property (SCR) for all data folders

To create a basic Exchange 2000 Web Application

Web pages are created in the Public folders. It is important to store the Web pages in the Public folder within the subdirectory of the virtual directory that is created using Internet Services Manager.

To create a new Web page without the wizard, ensure that the new Web page is anchored in the folder that was created using Internet Services Manager.

If you have not done so already, go into Internet Services Manager and find the Public folder. Right-click the Public folder. Select New Server Extensions Web and walk through the steps of the New SubWeb Wizard.

To create a new Web page running the Exchange 2000 Wizard

  1. In FrontPage 2000, select New Web from the File menu.
  2. Select Basic Exchange 2000 Web.
  3. Specify the location of the new Web page. The location is a subdirectory of the newly-created folder.
  4. Enter the name for the application.
  5. Select the type of data to use in the application.
  6. Select one of the choices in the drop-down menu: other, appointments, documents, messages/posts, or people.
  7. Enter the properties to apply to the selected items.
  8. Add any properties to the list generated by the wizard. For example, add a title.
  9. Pick a field to serve as the title field.

The application prompts the user for their name, password, and domain. Remember that the user name you enter must be a member of the Front Page Admin group. Under Users, the group is listed as servername/Admin.

The Folder List contains a resources folder. The folder lists the pieces of the application. Save the FrontPage Web and test it in your browser.

When the wizard finishes, the end user has both a view and a form for entering data in Exchange 2000 Server. The forms can then be customized with the exact properties required by the user.

The forms directory contains two forms, a DefaultListView.htm (the default form) and Application_item_form.htm. DefaultListView.htm has a view and a link to Application_item_form.htm. The Application_item_form.htm enables the user to enter information into a text box and to store it as a custom property.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Customizing a Web Storage System Form

Microsoft® FrontPage® 2000 Design Time Controls (DTCs) can be used to customize a Web Storage System Form.

To add a design time control to a Web Storage System form

  1. From the Insert menu, click Design Time Control from the Advanced menu.
  2. Select the fields to display on the Web page.
  3. Position the control on the Web page.

To customize a design time control

  1. Select a view to customize.
  2. Choose the views to display on the Web page. For example, show image path lines or not, show icons, allow drag and drop.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


FrontPage Extensions Components

Installing Microsoft® FrontPage® Extensions adds the WSS Forms menu and components. The installed components include Form Properties, Field Name, Goto Databound Tag, Insert Folder View, Insert Outlook Web Access View, Form Registration Tool, and Web Storage System Options.

Form Properties

Form Properties allows you to set, view, or edit the content class of the current Web page. The dialog box also allows you to set the redirect string and the target.

Field Name/Choose Property

The Choose Property dialog box appears when the user selects the Field Name dialog box. The major tabs are: Form, Application, and All.

Form

The Form tab lists the application schema used only on the current form.

Application

The Application tab lists all content classes that are referenced within the application.

All

The All tab lists the global schema.

Insert Folder View

The Design Time Control Properties dialog box is available from the WSS Forms menu. The dialog box has tabs for Columns, General, Object Tag, and Parameters.

The Columns tab allows the user to add, edit, delete, or rearrange the columns for the View.

Form Registration Tool

The Form Registration Tool dialog box is available from the WSS Forms menu.

Using the dialog box, users can view, add, edit, or delete form registrations.

When adding a form registration, the user enters the following:

  • The description
  • The form URL
  • A command from a list of commands
  • A browser from a list of browsers
  • An item type

When the advanced button is selected, the dialog box expands to display the following fields:

  • Execute parameters
  • Browser version
  • Execute URL
  • Request
  • Language
  • Platform
  • Binding

Web Storage Systems Options

The Options dialog box is available from the WSS Forms menu. Use the Options dialog box to change the default folder.

FrontPage 2000 automatically names field names when a field is created. Check this box to rename fields.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Adding a View Behavior to a Web Storage System Form

Views can be added to the Web Storage System Form by selecting the view and opening the Properties dialog box. To add a view:

  1. Select the view.
  2. Right-click the view to change the properties.
  3. Name the behaviors using the Form Field Properties.
  4. Save the form to a location within the Web Storage System in a provided location (under Public).
Note To view the form, click the Preview tab in Microsoft® FrontPage® 2000. The user must preview the form inside the browser to see the populated view.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Server Component Behaviors

Microsoft® FrontPage® Extensions for Web Storage System Forms make it possible to create Web Storage System Forms with views.

Inserting a View

A view is a tabular representation of data in the Web Storage System.

  1. Insert a view by either selecting Insert Design Time Control from the FrontPage Extensions menu or from the WSSForms toolbar.
  2. Click the Add button on the Properties dialog box to add columns.

To browse available schema, click Browse.

Customizing the view

The Web author can choose the properties that the view displays. For example, the view can display image path lines, hide icons, and allow drag and drop functionality.

  1. Right-click the view.
  2. Click Properties and modify the column order, column width, titles, contents, or other properties.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Programming Tasks

The topics in this section describe the programming tasks associated with Web Storage System forms. They include information about how to build and register a Web Storage System form, how to use Microsoft® Outlook® Web Access views in a Web page, and how to reuse pieces of Outlook Web Access in a Web page.

For more information about programming tasks for Web Storage System forms, see the following sections:

Registering a Web Storage System Form

Reusing Outlook Web Access Components in a Web Page

Working with Web Storage System Form Fields

Using Web Form Views in a Web Part

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Registering a Web Storage System Form

Custom Web Storage System Forms can be registered in the Web Storage System. After forms are properly registered, Microsoft® Exchange 2000 Server displays the custom forms.

To register a Web Storage System Form manually

  1. Create the form in Microsoft® FrontPage® or the editor most appropriate to your needs.
  2. Modify the form to add the functionality that you want. You can also choose to add the form itself to the store.
  3. Log on to the Exchange Server computer as a user with rights to write to the intended directory.
  4. Register the Web form in the store.

For additional information about registering Web Storage System forms, see the following topics:

Registering a Web Storage System Form Using PROPPATCH

Using ADO to Set the SCR and Default Document Properties

Binding Messages to Custom Forms

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Registering a Web Storage System Form Using PROPPATCH

This example assumes a Web page with a button that triggers the DoDocRegister function. Log on as a user authorized to write to the store before you run the code.

function DoDocRegister()
{
m_httpsaverequest = new ActiveXObject("microsoft.xmlhttp");
bstrRequestXML = "<?xml version='1.0'?><a:propertyupdate xmlns:a='DAV:' xmlns:b='urn:schemas:mailheader:'>";
bstrRequestXML +="<a:set><a:prop>";
bstrRequestXML +="<a:contentclass>urn:schemas-microsoft-com:office:forms#registration</a:contentclass>";
bstrRequestXML += "</a:prop></a:set></a:propertyupdate>";
m_httpsaverequest.open("PROPPATCH", docform.url, false);
m_httpsaverequest.setRequestHeader("Content-type", "text/xml");
// send takes one parameter which is the requestBody to use
// if status property is in 200 range, then everything's OK
m_httpsaverequest.send(bstrRequestXML);
//Response is XML DOM object that can be inspected
bstrXML = m_httpsaverequest.responseXML;
// idMsgViewer2.update();  // do whatever updates are necessary
m_httpsaverequest = null;
}

The following Extensible Markup Language (XML) example illustrates useful fields in XML format that you need to register a form. For an explanation of each of the fields, see Form Definition Properties. The form uses a custom content class named myclass. Processing is handled by an Active Server Pages (ASP) file named Process.asp.

<prop>
<b:contentclass>urn:schemas-microsoft-com:office:forms#registration</b:contentclass>
<f:formurl>process.asp</f:formurl>
<f:cmd></f:cmd>
<f:contentclass>urn:contentclasses:myclass</f:contentclass>
<f:executeurl>process.asp</f:executeurl>
<f:browser>*</f:browser>
<f:contentstate>*</f:contentstate>
<f:language>*</f:language>
<f:majorver>=5</f:majorver>
<f:minorver>*</f:minorver>
<f:platform>*</f:platform>
<f:request>GET</f:request>
</prop>

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Using ADO to Set the SCR and Default Document Properties

Web items can be registered in the store as the default page for a particular folder. You can do this by setting the DAV:defaultdocument to the name of the item.

When the user opens the folder, the default page appears instead of the usual list of files. (The default page is set to the default document properties.)

This example uses an Active Server Pages (ASP) Web page to create a Microsoft® ActiveX® Data Objects (ADO) database (ADODB) object. It updates the Schema Collection Reference (SCR) and the default document properties.

Before you run the code, make sure that you log on as a user authorized to write to the store.

Note To return to the original default folder, set the default document property to "".
Note Registering the form will override the default document setting.

VBScript

Note The following example uses a file URL with the Exchange OLE DB (ExOLEDB) provider. The ExOLEDB provider also supports the HTTP URL scheme. Using the HTTP URL scheme allows both client and server applications to use a single URL scheme.
<HTML>
<HEAD>
<%@ LANGUAGE = "VBScript" %>
<%
Const adModeReadWrite       = 3
Const adFailIfNotExists     = -1
Const adCreateNonCollection = 0

Dim strURL
strURL = "file://./backofficestorage/ServerName.microsoft.com/public folders/myappfolder3/"

Dim Rec
Set Rec = CreateObject("ADODB.Record")

response.write strURL

Rec.Open strURL,,adModeReadWrite, adFailIfNotExists
response.write "<P>"

Dim Flds
Set Flds = Rec.Fields

' Set the SCR and the default document
Flds("urn:schemas-microsoft-com:exch-data:schema-collection-ref") = strURL & "schema5h/"
Flds("DAV:defaultdocument") = "default2.htm"
Flds.Update

Response.write(Err.number) & "<P>"
response.write"<H3>SUCCESS</H3>"

Rec.Close
%>

</HEAD>
<BODY>
</BODY>
</HTML>

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Binding Messages to Custom Forms

Developers often want a user to view a custom form when the user opens a message.

The custom form example consists of two files, InstallMessage.vbs and CustomMessage.asp. InstallMessage.vbs creates the necessary folders, sets the Schema Collection Reference (SCR), and performs the form registration. The Active Server Pages (ASP) file is executed whenever the user opens a message in that particular folder.

To run the custom form example

  1. Copy InstallMessage.vbs and CustomMessage.asp to your server.
  2. Run the .vbs file, typing in the appropriate URL when requested.
  3. Copy the CustomMessage.asp file into the resulting Bin directory.
  4. Go to that folder inside Outlook Web Access and create a new message.
  5. While still inside Outlook Web Access, click the icon to check for new messages and then double-click the message created in Step 4.
  6. The custom form appears.

The form itself is intentionally very simple. It only shows some HTML-generated text and the subject of the opened message.

Note In Exchange System Manager, turn on Script Execute Permissions for ASP pages, and Scripts and Executables for Internet Server Application Programming Interface (ISAPI) filters. Otherwise, you will receive a 403 Permission Denied error.

InstallMessage.VBS

Install
Sub Install
'Get the folder
sFolder = InputBox("Please enter the URL to the folder: example http://serverName/public/foldername","Setup Instructions")
If Trim(sFolder) = "" Then
    Exit Sub
End If

'Create the app folder, pointing its SCR to the BIN subfolder
Set oDest = CreateObject("CDO.Folder")
oDest.Fields("urn:schemas-microsoft-com:exch-data:schema-collection-ref") = sFolder + "\bin"
odest.Fields("DAV:contentclass") = "urn:content-classes:folder"
oDest.Fields.Update
oDest.DataSource.SaveTo sFolder
'Create the BIN folder and make it invisible
Set oDest = CreateObject("CDO.Folder")
oDest.Fields("DAV:ishidden") = True
oDest.Fields.Update
oDest.DataSource.SaveTo sFolder +  "/bin"

'Fill the BIN folder with form registrations

Set oCon = CreateObject("ADODB.Connection")
oCon.ConnectionString = sFolder + "/bin"
oCon.Provider = "ExOledb.Datasource"
oCon.Open

'----------------------------------------------------
'Register the default page for the folder
Set oRec = CreateObject("ADODB.Record")
oRec.Open "default.reg", oCon, 3, 0
oRec.Fields("DAV:contentclass") = "urn:schemas-microsoft-com:office:forms#registration"
oRec.Fields("urn:schemas-microsoft-com:office:forms#contentclass") = "urn:content-classes:message"
oRec.Fields("urn:schemas-microsoft-com:office:forms#cmd") = "open"
oRec.Fields("urn:schemas-microsoft-com:office:forms#formurl") = "CustomMessage.asp"
oRec.Fields("urn:schemas-microsoft-com:office:forms#executeurl") = "CustomMessage.asp"
oRec.Fields.Update
oRec.Close

'Further instructions
MsgBox "Copy CustomMessage.ASP into the BIN directory. Enable script execution on the directory.", 64, "Further Instructions"

End Sub

CustomMessage.ASP

<%@Language=VBScript%>
<html>
<body>

<%
dataurl = request.querystring("dataurl")
Set c = Server.CreateObject("ADODB.Connection")
c.ConnectionString = dataurl
c.Provider = "ExOledb.Datasource"
c.Open
Set r = Server.CreateObject("ADODB.Record")
r.Open dataurl, c, 3
%>

<form class="form" method="post" action="<%=request.querystring("dataurl")%>?Cmd=save">

<h3>Message</h3>
Subject:<input type="text" name="urn:schemas:mailheader:subject" value="<%=r("urn:schemas:mailheader:subject")%>"

<input type="submit" value="Save">
</form>

<%
r.Close
c.Close
%>
</body>
</html>

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Reusing Outlook Web Access Components in a Web Page

Microsoft® Outlook® Web Access views can be added to a Web page. They can be nested inside Frame, IFrame, and Table HTML elements. Nesting allows the Web designer to control the appearance and the functionality of the page. Adjusting the URL parameters modifies the appearance of the view. The following topics provide information about loading an Outlook Web Access view in an IFrame and a Frame.

Loading an Outlook Web Access View in an IFrame

Loading an Outlook Web Access View in a Frame

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Loading an Outlook Web Access View in an IFrame

Microsoft® Outlook® Web Access views can be displayed in an IFrame. IFrames are inline floating frames that provide positioning control on a Web page. For example, Web page authors can specify height and width parameters using IFrames.

IFrames are supported in Microsoft® Internet Explorer 4.0 or later. For more information about IFrames, see the MSDN Library.

Example

This example loads the user inbox into an IFrame. The IFrame provides links to the user’s inbox and outbox.

<html>
<head>
</head>
<body>
<hr>
<p>Example of reusing an Outlook Web Access view and embedding the view in an IFrame.</p>
<a href="http://servername1/exchange/user1/inbox?Cmd=contents">Inbox</a>
<a href="http://servername1/exchange/user1/outbox?Cmd=contents">Outbox</a>
<p>
<iframe name = "main", src="http://servername1/exchange/user1/inbox?Cmd=contents",
width = 90%, height = 70%>
</iframe>
</body>
</html>

Note Internet Explorer 4.0 or later is required to view this example.

When the Web page appears, the user inbox is nested inside the IFrame. If the user selects the inbox or outbox view, the appropriate view is displayed inside the IFrame.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Loading an Outlook Web Access View in a Frame

Microsoft® Outlook® Web Access views can be displayed in a frame. Frames are supported by browsers that support the HTML 3.2 standard.

This example creates a frameset with two frames. A table of contents is loaded in the left frame that allows the user to choose an inbox and outbox. When the user selects inbox or outbox, the appropriate view appears in the frame on the right side.

This example uses frame.htm, toc.htm, and main.htm. Frame.htm creates the frameset, toc.htm displays the table of contents, and main.htm displays the inbox and outbox views depending on the user selection.

frame.htm

<html>
<frameset frameborder = 1 bordercolor = "#000000" cols = "80, 300">
  <frame frameborder = 1 src = "toc.htm" name = "toc">
  <frame frameborder = 1 src = "main.htm" name = "main">
</frameset>
<noframes>Need a browser that supports frames</noframes>
</html>

toc.htm

<html>
<body>
<h1>Logo</h1>
<hr>
<p>Select Inbox or Outbox</p>
<a href="http://servername1/exchange/user1/inbox?Cmd=contents" target= "main">Inbox</a>
<br>
<a href="http://servername1/exchange/user1/outbox?Cmd=contents" target= "main">Outbox</a>
</body>
</html>

main.htm

<html>
 <body>
   <br>
   <p>Click on a menu choice to the left</p>
 </body>
</html>

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Working with Web Storage System Form Fields

Web Storage System Forms allow the binding of data from the Web Storage System into fields in a Web Storage System Form. The name and class parameters are added to the HTML to define each field.

The example in this topic demonstrates the following:

  • Use of name and class parameters in the code.
  • Supported bindings of data types to controls, including the markup format and function.
  • Supported data formats that can be specified as part of the markup.

formfield.htm

<html>
<head>
<title>Application</title>
</head>
<body>
<form method="POST" class="form" id="theform" actionspec="%dataurl%?cmd=contents">
<H1>Application</H1>
<BR>
<table height="1">
<tr>
<td height="32">urn:schemas:contacts:givenName:
<td height="32"> <input type="text" name="urn:schemas:contacts:givenName" class="field" form="theform" size="20">
</tr>
<tr>
<td height="28">DAV:creationdate:
<td height="28"> <input type="text" name="DAV:creationdate" class="field" form="theform" size="20">
</tr>
<tr>
<td height="34">Title:</td>
<td height="34"> <input type="text" name="Title" class="field" form="theform" size="20">
</tr>
<tr>
<td height="29">urn:schemas:contacts:middlename:
<td height="29"> <input type="text" name="urn:schemas:contacts:middlename" class="field" form="theform" size="20">
</tr>
<tr>
<td height="31">urn:schemas:contacts:sn:
<td height="31"> <input type="text" name="urn:schemas:contacts:sn" class="field" form="theform" size="20">
</tr>
<tr>
<td height="38">urn:schemas:contacts:officetelephonenumber:
<td height="38"> <input type="text" name="urn:schemas:contacts:officetelephonenumber" class="field" form="theform" size="20">
</tr>
<tr>
<td height="31">urn:schemas:mailheader:organization:
<td height="31"> <input type="text" name="urn:schemas:mailheader:organization" class="field" form="theform" size="20">
</tr>
<tr>
<td height="31">
<td height="31"><input type="submit" value="Submit" name="B1">
  <input type="reset" value="Reset" name="B2">
  <BR>

   <BR>
<input type="hidden" name="DAV:contentclass" value="Application" form="theform">
<BR>
<input type="hidden" name="http://schemas.microsoft.com/exchange/nosave/hintforurl" value="Title">
</table>

</form>
</body>

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Using Web Form Views in a Web Part

The following sample code shows the form registration that allows an HTTP request to render the content of an Exchange folder using exwform.dll as the rendering engine and page1.htm as the form. The value, server, in the form:binding tag indicates the page is rendered on the server. The resulting HTML fragment can be integrated into a Document Object Model (DOM) and used to populate a Web part in a digital dashboard.

<g:propertyupdate xmlns:g="DAV:" xmlns:h="urn:schemas:mailheader:"  xmlns:form="urn:schemas-microsoft-com:office:forms">
   <g:set>
      <g:prop>
         <form:cmd>ShowView</form:cmd>
         <form:request>GET</form:request>
         <form:contentclass>urn:content-classes:folder</form:contentclass>
         <form:executeparameters></form:executeparameters>

         <form:executeurl>/exchweb/bin/exwform.dll</form:executeurl>
         <form:formurl>page1.htm</form:formurl>

         <h:content-class>urn:schemas-microsoft-com:office:forms#registration</h:content-class>
         <form:binding>server</form:binding>
      </g:prop>
   </g:set>
</g:propertyupdate>

An HTTP request to http://domain/exchange/user/Digital%20Dashboard/folderview/resources/?Cmd=ShowView will go through the form registration. If the browser supports the view behavior, then exwform.dll will emit the view unmodified. Otherwise, it will create a table view on the server.

Related Topics

  • Form Definition Properties
  • Overview of Web Storage System Forms

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Example Code

Topics in this section contain code samples that show the implementation of Web Storage System Form technology features.

For code samples that apply to building Web Storage System Forms, see the following section:

Form Registration Examples

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Form Registration Examples

A form registration is a set of form-specific properties. The Forms Registry uses the form registration to choose which form to display. The form definition is a single record in an application schema folder in the Web Storage System store.

The form registration records the form definition properties.

The Content Classes of items displayed by this form are required. All other form registration properties are optional.

The most basic form registration would consist of:

  • The DAV content class of the form registration
  • The content class of the form
  • The URL of the form (not necessary in some scenarios)
  • The executeURL field

Registration Security

To register a form in a folder, you must have permissions to modify items in that folder.

Security is based on the Microsoft® Windows® 2000 and Microsoft® Windows NT® security model and on the security identifiers (SIDs) of real network users. Discretionary access control lists (ACLs) can be set on any item in the Web Storage System.

Namespaces

An XML namespace is a label that accompanies a set of elements or attributes. The namespace uniquely identifies these elements or attributes by limiting the scope.

The following is an example of the DAV namespace Uniform Resource Identifier (URI):

xmlns:d="DAV:"

The following is an example of a namespace URI for the forms property in schemas-microsoft-com:office

xmlns:f="urn:schemas-microsoft-com:office:forms"

For the server and client examples that follow, the following XML namespaces have been declared:

xmlns:d="DAV:"
xmlns:b="urn:schemas:mailheader:"
xmlns:f="urn:schemas-microsoft-com:office:forms"
xmlns:sales="sales:"
xmlns:s="urn:schemas-microsoft-com:exch-data:"
xmlns:c="urn:schemas:calendar:">

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


WebDAV Example

This example creates a form registration for messages. The form that will be displayed is Form1.htm.

<?xml version="1.0"?>
<g:propertyupdate xmlns:g="DAV:"  xmlns:form="urn:schemas-microsoft-com:office:forms">
   <g:set>
      <g:prop>
    <g:contentclass>urn:schemas-microsoft-com:office:forms#registration</g:contentclass>
      </g:prop>
      <g:prop><form:browser>*</form:browser></g:prop>
      <g:prop><form:cmd>*</form:cmd></g:prop>
      <g:prop><form:contentclass>urn:content-classes:message</form:contentclass></g:prop>
      <g:prop><form:contentstate>*</form:contentstate></g:prop>
      <g:prop><form:executeurl>process.asp</form:executeurl> </g:prop>
      <g:prop><form:formurl>/myforms/form1.htm</form:formurl></g:prop>
      <g:prop><form:language>en</form:language></g:prop>
      <g:prop><form:majorver>*</form:majorver></g:prop>
      <g:prop><form:messagestate>*</form:messagestate></g:prop>
      <g:prop><form:minorver>*</form:minorver></g:prop>
      <g:prop><form:platform>WinNT</form:platform></g:prop>
      <g:prop><form:request>GET</form:request></g:prop>
   </g:set>
</g:propertyupdate>

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Testapp Example

Testapp is a folder inside the Public folder. The major version is “=5,” which represents Microsoft® Internet Explorer 5 or later.

Note If the major version is less than five, it is listed as &lt5. The &lt; is required because <5 is not interpreted correctly.
<resource>
<href>testapp/editsales.html</href>
<contenttype>text/html</contenttype>
<prop>
<b:contentclass>urn:schemas-microsoft-com:office:forms#registration</b:contentclass>
<f:formurl>/testapp/editsalesman.html</f:formurl>
<f:cmd></f:cmd>
<f:contentclass>urn:content-classes:salesman</f:contentclass>
<f:executeurl>/exchweb/bin/process.asp</f:executeurl>
<f:browser>*</f:browser>
<f:contentstate>*</f:contentstate>
<f:language>*</f:language>
<f:majorver>=5</f:majorver>
<f:minorver>*</f:minorver>
<f:messagestate>*</f:messagestate>
<f:platform>*</f:platform>
<f:request>GET</f:request>
</prop>
</resource>

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Related Topics

The following sections includes topics that provide additional information about the Web Storage System that is useful when building Web Storage System forms:

Web Storage System Schema

Web Storage System Item Properties

Working with Folders and Items

Accessing the Web Storage System

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Building Applications That Manage Workflow

Microsoft® Exchange 2000 Server provides a foundation for building robust applications that manage workflow processes.

The topics in this section describe how to develop workflow applications with Exchange 2000 Server, and how to create event sinks that respond to state transitions of your workflow processes.

Frequently Asked Questions

Introduction

Before You Start

Concepts and Architecture

Programming Tasks

Example Code

Related Topics

Appendixes

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Frequently Asked Questions

This topic covers frequently asked questions about programming applications that manage workflow.

CDO Workflow

  • What steps must I perform to configure my server to run CDO Workflow applications?

  • How do I get Just-in-Time script debugging set up, so I can debug workflow scripts?

  • Can I replicate Exchange 2000 workflow folders to Exchange 5.5 servers?

Can I Replicate Exchange 2000 Workflow Folders to Exchange 5.5 Servers?

Replication of Microsoft® Exchange 2000 Server workflow-enabled folders to Exchange Server 5.5 servers is not supported. Exchange 2000 Server workflow is based on synchronous events, which Exchange 5.5 does not support. The workflow event sink does not process changes made on the computer running Exchange 5.5. Changes made to the folder on the computer running Exchange 5.5 are not processed when the folder is replicated to a computer running Exchange 2000 Server. The workflow event sink only handles changes made on the local computer running Exchange 2000 Server. The event sink is designed this way to prevent duplicate workflow processes.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Introduction

Workflow applications model business processes. Workflow applications automate the flow of information between the process steps, and assist in performing the steps. Applications that manage workflow processes are used to plan, design, implement, and measure the effectiveness of workflow automation. Collaboration Data Objects (CDO) Workflow is built-in functionality provided with Microsoft® Exchange 2000 Server. It enables you to design workflow applications without having to write the fundamental code that accesses, modifies, and controls data. CDO Workflow for Exchange 2000 Server includes a workflow engine, modeling tools, and an event sink.

This section discusses the following topics:

Workflow Overview

Using Built-in Workflow Functionality

Creating Workflow Event Sinks and Tools

Controlling Workflow Management Access with Security Modes

Deploying Event Sinks and Applications That Manage Workflow

Testing and Debugging Event Sinks and Applications That Manage Workflow

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Workflow Overview

The term workflow describes applications that are modeled on business processes, such as an expense report approval system. Typical workflow applications include the following:

  • Forms routing and approval
  • Document review and publishing
  • Issue tracking

You could write these kinds of applications from scratch in almost any programming language, but you can simplify the task by using the built-in workflow engine and specialized workflow modeling tools provided with Microsoft® Exchange 2000 Server.

Modeling tools enable you to specify the overall design or flow of a business process in a simple, high-level representation called a process definition. In an expense report, for example, you could define a process in which reports totaling less than $50 are routed directly to your accounting department, whereas reports equal to or greater than $50 are routed to a manager for approval.

The modeling tools enable you to define the various states of the document—for example, submitted, needs approval, or approved. You define transitions between states by using actions in Microsoft® Visual Basic® Scripting Edition (VBScript). You can easily modify or extend the process definition without rewriting all of the fundamental application code.

You use the tool to associate the process definition with a folder. When anything happens in the folder, the Workflow Event Sink calls the workflow engine, which runs your application. The workflow engine executes and manages individual instances of a process definition; these are also called process instances.

Collaboration Data Objects (CDO) workflow objects for Exchange provide a built-in workflow engine and an object model for programming that engine. You can create process definitions, which consist of a table of actions or rules that define the business process. The following table shows a single, simplified row from an action table.

Row ID | Caption | State | NewState | EventType | Condition | Action
"1" | "Create" | "" | "Submitted" | "OnCreate" | "IsValidExpenseForm()" | "CheckDollarAmount"

The workflow engine evaluates the process definition to see which actions it needs to run. Next, it executes scripts or Component Object Model (COM) objects to perform application-specific business logic.

Using a CDO workflow event sink makes it easier for you to integrate workflow into existing applications. For example, you can register the event sink in a folder, where the event sink intercepts all changes made in that folder, and automatically calls the workflow engine on the application's behalf. If you have existing applications in that folder, they continue to create, modify, or delete items. The event sink also connects to the system timer events to automate expiring items, overdue work, or other cleanup tasks. The event sink works well in scenarios in which users are creating or editing documents using off-the-shelf applications such as Microsoft® Word or Microsoft® Excel.

CDO workflow applications build on the Web Storage System architecture and they must run on a server running Exchange 2000 Server. You install workflow applications into either a public folder or a private Inbox folder. You register the event sink in folders that you own. Server administrators must determine and configure the following for each server:

  • Who is authorized to register workflows on that computer.
  • Who might write unlimited workflow scripts as opposed to "sandboxed" workflow scripts.

Some earlier versions of Exchange (5.5 with Service Pack 1 and later) included Routing Objects libraries, which are helper objects for building simple document routing applications. Although Routing Objects are in some ways similar to the new CDO workflow objects, they were designed only for e-mail routing applications based on MAPI, and don't take advantage of the new Web Storage System features. Exchange 2000 Server is still compatible with existing MAPI applications, including Routing Objects. If you want to build a routing application that runs on both Exchange Server 5.5 and Exchange 2000 Server, you use MAPI and the Routing Objects libraries. If you want to write Web-based workflow applications or use new Web Storage System features, you should use Exchange 2000 Server and CDO workflow objects.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Using Built-in Workflow Functionality

Workflow application developers should have a working knowledge of Microsoft® Visual Basic® Scripting Edition (VBScript). They can use VBScript with the Workflow Designer and built-in Collaboration Data Objects (CDO) workflow functionality to create workflow applications. The built-in functionality includes the workflow engine and workflow event sink. These are installed by default with Microsoft® Exchange 2000 Server.

Microsoft also provides a graphical user interface (GUI) application tool called Workflow Designer for Exchange 2000 Server. This tool can be installed on the server or on a client computer. Use Workflow Designer to create workflow applications that take advantage of built-in workflow functionality. For detailed information about how to use Workflow Designer, see the Workflow Designer Help.

Before using Workflow Designer, you need to do the following:

  1. Get workflow registration privileges. You need to be a member of the Can register workflow role of the workflow event sink Component Object Model (COM)+ package.
  2. Get workflow author privileges. You can have either a restricted or a privileged workflow author role. To have a restricted role, there is nothing you need to do. To have a privileged author role, you must be added to the COM+ role for the workflow event sink.
  3. Create a new public folder. You need to be the folder owner to run Workflow Designer on the folder.

After you have installed Workflow Designer, established yourself as a workflow author and registrar, and created a new folder for your workflow design, you can use VBScript to associate your business logic with events in your folder, such as creating an item, changing an item, or deleting an item.

The following topics provide an overview of Workflow Designer and of workflow objects:

Modeling Business Processes

Developing Typical Workflow Applications

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Modeling Business Processes

Workflow Designer for Microsoft® Exchange 2000 Server is a tool for constructing a diagram that is translated by the tool into an ActionTable. It provides workflow authors with a visual tool for creating their own ProcessDefinition logic. You can use Workflow Designer to do the following:

  • Model the workflow logic.
  • Add script actions and conditions to the logic.
  • Save the ProcessDefinition in a workflow folder.

The following illustration shows the default process when you start Exchange Workflow Designer.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Developing Typical Workflow Applications

Microsoft® Exchange 2000 Server workflow components include the workflow engine and workflow event sink. The engine and event sink create the run-time objects that implement your design and provide your script with the correct data. You can use the WorkflowSession object in condition and action scripts that you add with Workflow Designer. The WorkflowSession object is the staple of the typical workflow application developer. Its properties expose the functionality of the IAuditTrail, ISessionProps, IMembers, and IWorkflowMessage interfaces. The IAuditTrail Interface provides a way to log workflow activity for auditing, performance analysis, and debugging. The IWorkflowMessage Interface enables your workflow application to use e-mail messages in workflow processes.

WorkflowSession Object

The workflow engine passes this intrinsic object to the script host environment. The WorkflowSession object provides the following functionality to your script:

  • A Fields collection representing the ProcessInstance that is undergoing transition. Your scripts can modify this row to create desirable side effects for a state transition. For instance, new contact information gets saved in a folder, so your script adds sales region ID and regional manager ID fields to the row and inserts data into those fields.
  • Write access to the AuditTrail. Your script can pass errors and other information back to the WorkflowSession object that is logged by your audit trail provider. An audit trail provider is any registered Component Object Model (COM) object that implements the IAuditTrail interface.
  • A method for sending and tracking e-mail notifications and responses associated with a specific ProcessInstance in its TrackingTable property. This property returns a recordset. Your script can use the recordset to tabulate responses or work with custom form data.
  • The ability to control item-level security of the item undergoing transition. The WorkflowSession object exposes the ItemReaders and ItemAuthors collections. Your scripts can modify these collections to give readers and authors exclusive privileges to documents.
  • Run-time environment information such as the names of the domain and server that workflow is running on and the context of the user who triggered the workflow transition.

You can see a graphical representation of the WorkflowSession object model in CDO for Workflow Objects.

AuditTrailEventLog Object

You can access the audit trail using the WorkflowSession object by calling AddAuditEntry. Microsoft provides the AuditTrailEventLog coclass with the workflow components. This is a sample provider that you can use to write to the application log in Event Viewer. Workflow Designer uses this provider by default. Advanced developers can develop providers by implementing the IAuditTrail interface.

WorkflowMessage Object

The WorkflowMessage object provides several useful e-mail features for workflow applications. Using this object, you can:

  • Send e-mail in restricted mode, which prevents object instantiation.
  • Track responses to workflow e-mails.
  • Make workflow e-mails part of the workflow transaction so that a "send" is aborted if the transaction fails.

A WorkflowMessage object is not cocreatable; you access its functionality through the WorkflowSession object. The WorkflowSession object provides the GetNewWorkflowMessage method for sending e-mail notifications. The WorkflowMessage interface contains a subset of the IMessage interface and adds one unique method— SendWorkflowMessage.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Creating Workflow Event Sinks and Tools

Advanced developers may want to create their own event sink or workflow process designer tool. If you are an advanced developer, you can use the interfaces provided by the CDO workflow objects to make direct calls to the workflow engine; you can also design workflow processes.

The following topics describe how the workflow engine controls the current state of a document in a workflow. To use the engine with your event sink or designer tool, you should be familiar with how the workflow engine operates.

Developing Advanced Workflow Applications

Application Architecture

Workflow Components

Workflow Variations

Workflow Process Definition

Controlling Workflow Management Access with Security Modes

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Developing Advanced Workflow Applications

You can develop your own workflow applications by making direct calls to the ProcessDefinition object. You can use Microsoft® ActiveX® Data Objects (ADO), OLE DB, or World Wide Web Distributed Authoring and Versioning (WebDAV) to create the necessary data bindings.

To develop a workflow application using any language that supports Component Object Model (COM):

  1. Define an action table.
  2. Develop script functions or custom COM objects to represent your business logic.
  3. Create a ProcessDefinition.
  4. Register the workflow event sink in the workflow folder.

The first three steps constitute your workflow design. In the final step, you save your workflow design as an item in a public folder and create an association between the workflow event sink and Web Storage System synchronous events.

Defining an ActionTable

The ActionTable encapsulates the logic of your design. You define the ActionTable by laying out the rules for documents that are saved or posted in the specified folder. A rule tells the workflow engine, "If a document is in a given state and a given condition is true, then execute the given action." Each row in the table addresses a combination of state, condition, and action. The ActionTable schema includes 14 properties that are defined in the IProcessDefinition Interface.

Developing Script Functions

ActionTable fields include Condition, Action, and CompensatingAction. You can include script functions within these fields of the ActionTable, and you can have a reference to a CommonScript function in any of these fields. You can declare the CommonScript as a separate item or include it as the default stream of the IProcessDefinition item.

If you are a privileged workflow author, you can use a COM object as a Condition, Action, or CompensatingAction, in which case the ActionTable contains the ProgID for your COM object in the respective field(s). The ActionTable requires you to set flags indicating whether conditions and actions contain COM objects or script.

Creating a ProcessDefinition

After you have created the two critical pieces of your workflow design — the ActionTable and the CommonScript — you can associate them with a ProcessDefinition object. You can then set other important properties of your design, such as:

  • The security mode that you want the process to execute under (Mode).
  • The logging tool you want to use for monitoring and debugging your design ( AuditTrailProvider).

After you set the ProcessDefinition properties, you save them as an item in the workflow folder by using their DataSource property. You can also use the ADO Fields collection with the Web Storage System schema property names to set these values. If you have physical access to the server, you can use Collaboration Data Objects (CDO) workflow interfaces to set these properties. For remote scenarios, you need to use ADO.

Registering the Workflow Event Sink

To associate your business logic with Web Storage System events, you need to register the workflow event sink in a Web Storage System folder. The event sink needs to be registered for the following three events:

  • OnSyncSave
  • OnSyncDelete
  • OnTimer

You register the event sink by creating a new Web Storage System item. This item represents a store event registration for the event that you want to trap. To create the item, you must set the Web Storage System schema properties to identify the event type, the ProgID of the workflow event sink, and any configuration information.

Use the OnSyncSave event registration to configure the following properties of the application:

  • The adhocflows property, which tells the workflow run-time environment whether to enable individual workflow processes to define their own behavior. New items can contain their own ProcessDefinition.
  • The defaultprocessdefinition property, which indicates the default behavior for documents in the folder. This is necessary where ad hoc processes are not allowed, or where ad hoc processes are allowed but a new item does not contain its own ProcessDefinition.
  • The enabledebug property, which you set by using the registration item. This enables the Just-In-Time (JIT) script debugger. For the JIT script debugger to work, three requirements must be met.
  • The disablesuccessentries property, which you set by using the registration item. This limits the types of entries made in the audit trail.

Calling IProcessInstance Advance

You can also develop your own workflow event sink for calling the workflow engine ( Advance) directly, by using the IProcessInstance object. Use ADO, OLE DB, or WebDAV to create the necessary bindings.

At a minimum, your event sink must:

  • Bind to the Web Storage System item that initiated the event.
  • Open a ProcessInstance object on the item.
  • Call the IProcessInstance method Advance.
  • Save the ProcessInstance item.

Related Topics

  • Registering a Workflow Event Sink
  • IProcessDefinition

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Application Architecture

A workflow application consists of forms and documents that a user manipulates; it also consists of tools on the server that manage those documents according to a predetermined set of rules. The application architecture includes two layers, which are discussed in the following topics:

Presentation Layer

Business Logic Layer

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Presentation Layer

A workflow application includes forms or documents with which the user interacts directly. This layer is called the presentation layer of the application. The presentation layer could be a Microsoft® Word document, a Web form, a Microsoft® Outlook® form, or some other type of presentation layer that you design. All of these work because workflow events are triggered by any save or post in the workflow folder and because the Microsoft Web Storage System provides heterogeneous document storage. What you use as your presentation layer is up to you, because it has no relationship to the functionality of Collaboration Data Objects (CDO) workflow objects. The presentation layer is independent of CDO workflow objects. It usually runs on a client computer.

Related Topics

  • Business Logic Layer

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Business Logic Layer

You use Collaboration Data Objects (CDO) workflow objects to design and run workflow applications. These applications contain the business rules that govern your document approval and routing processes. Whereas the presentation layer usually runs on a separate client computer, the business rules run on the same server as the Microsoft Web Storage System, where the target documents are stored. Your business logic or workflow layer operates in a process separate from the Web Storage System process.

Related Topics

  • Presentation Layer

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Workflow Components

Workflow components are installed automatically with Microsoft® Exchange 2000 Server. They include the workflow engine and the workflow event sink.

Workflow components run in the event sink host process. This process is separate from the Microsoft Web Storage System process. The event sink host process includes the workflow event sink, the workflow engine, and the script host. The rest of this section focuses on the workflow engine and event sink, which make up the core functionality of a workflow application.

Workflow Engine

Workflow Event Sink

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Workflow Engine

Microsoft® Exchange 2000 Server includes an in-process server (CDOWF.DLL) that implements the Advance method of the IProcessInstance, also known as the workflow engine. The workflow engine controls the state changes to documents in your workflow folder. The workflow event sink (CDOWFEVT.DLL) calls the workflow engine when an event fires in your workflow folder.

The following sequence diagram shows the flow of information between the processes in the workflow run time environment.

Application developers do not call the workflow engine directly, unless they are writing their own event sink, advanced ASP application, or other middle-tier component. ASP applications, event sinks, and middle-tier components can use the workflow engine by making direct calls to the IProcessInstance::Advance method. The workflow engine maintains document integrity based on the parameters that the event sink passes.

The workflow engine checks your process design when it is notified of an event. You define a workflow process and set it up to be executed based on Microsoft Web Storage System events or system events. The process design encapsulates the logic for advancing the state of your workflow documents. It includes script or Component Object Model (COM) actions and conditions. The following illustration shows an application folder with a default ProcessDefinition and several ProcessInstances.

In the preceding illustration, the workflow engine attempts to find a match between the event notification that it received and a rule in the process logic. When it finds a match, it executes the prescribed action. The workflow engine and the script host run in the event sink process and have access to the ProcessInstance and the user context.

The following illustration shows the event sink process hosting the script host and the workflow engine.

When the workflow engine finds an action table match and executes the action script or COM object, it passes to the host environment a WorkflowSession object with a Fields collection representing the ProcessInstance undergoing transition. Only the workflow engine can change the status of a ProcessInstance directly. The workflow engine ignores any changes to the current state property made by the user or by a script. The following illustration shows how workflow operates.

Related Topics

  • IProcessInstance Interface

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Workflow Event Sink

The workflow event sink is the interface between the Microsoft Web Storage System process and the workflow engine. The event sink is automatically registered as a Component Object Model (COM)+ application package when you install Microsoft® Exchange 2000 Server. You can view this package through the Component Services console, which is accessed on the Administrative Tools menu. The following illustration shows the Component Services console in Microsoft Management Console (MMC) with the event sink COM+ package installed.

The event sink receives event notifications from the Web Storage System process and makes the appropriate call to the workflow engine. See Workflow Engine for an illustration of the calling sequence. Applications that want to use the Collaboration Data Objects (CDO) workflow event sink must create the appropriate Web Storage System Event Registration items in their folder. If you are using the Exchange Workflow Designer, it registers the event sink for you automatically.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Workflow Variations

The following topics discuss how users access the workflow folder and how a workflow instance gets its process definition.

Web-based and E-mail Workflow Compared

Default and Ad Hoc Process Definitions

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Web-Based and E-mail Workflow Compared

Collaboration Data Objects (CDO) workflow objects support both Web-based workflow and e-mail workflow. The following sections explain the two types of workflow.

Web-Based Workflow

In Web-based workflow, users can connect directly to the Microsoft Web Storage System through the corporate network. Users can access and update Web Storage System items directly through their network credentials. If a client application updates a property on the work item, you update the workflow state depending on the value of this property. For example, a manager clicks an Approve box on a form (client) and saves it. Your workflow design moves the item from a "needs approval" state to an "approved" state.

You can use e-mail in this type of application only to send notification messages to users. These notification messages contain a URL that links to the actual work item that needs to be updated.

Because the user who connects directly to the Web Storage System has been authenticated by Microsoft® Windows® 2000 security, you can control access to data based on the user's identity. The WorkflowSession, ItemReaders, and ItemAuthors collections provide easy mechanisms to control access to individual items as they move through the workflow process. The following illustration shows the client computer directly connected to the Web Storage System server through the corporate network.

E-mail Workflow

In e-mail workflow, users need not be directly connected to the corporate network. Offline users can participate in workflow through the Internet by transmitting data in e-mail. In this case, CDO workflow updates the workflow state upon receipt of a message that correlates to an existing workflow process instance. Direct authentication of such messages by workflow is not possible. The following illustration shows a client participating in e-mail workflow without network credentials.

The system compares incoming messages to existing workflow process instances. If the system fails to correlate an incoming message, it considers that message a new process instance and starts a new workflow. Standard Simple Mail Transport Protocol (SMTP) mail does not always contain sufficient information for correlation. For example, some mailers have a message ID and some do not, or a message header can get rewritten. CDO workflow implements a reliable process to make sure that each outgoing and incoming workflow item or response has a unique correlation ID. The correlation ID feature requires Microsoft® Outlook® as the e-mail client.

Related Topics

  • IWorkflowSession.TrackingTable
  • IWorkflowMessage.SendWorkflowMessage

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Default and Ad Hoc Process Definitions

You can specify that new workflow items use a default workflow process or an ad hoc workflow process. There are four ways to define processes:

  • A client uses the default workflow process in a folder.
  • A client picks from one of many processes installed in a folder. In this scenario, the process definition must be hidden to prevent unintended editing or viewing.
  • A client picks a process definition from another folder. This requires that ad hoc workflow be enabled. Ad hoc workflows can run only in restricted mode. In this scenario, the process definition must be hidden to prevent unintended editing or viewing.
  • A client submits an item with an embedded process definition. This requires that ad hoc workflow be enabled. Ad hoc workflows can run only in restricted mode.

Default Process Definition

In a default process workflow, all documents in a workflow folder follow the same process definition. In this case, the process definition is stored at the folder level. Every new document created in that folder inherits a URL to the default process definition for that folder. You implement this type of process definition by setting the http://schemas.microsoft.com/cdo/workflow/defaultprocdefinition property on the OnSyncSave registration item in the workflow folder.

Client-Specified Process Definition

A client may specify one of many process definitions installed in a folder depending on the class of document, or the client may specify a process from another folder. For example, you might have different classes of documents that have different approval behaviors. You use a relative URL to specify the process definition (for example, MyProcessDesign1.wdm). To specify a process from another folder, you must set the Collaboration Data Objects (CDO) enumeration CdoWfAdhocFlows Enum flag directly with the Web Storage System schema property. This is part of the event sink registration. Ad hoc workflows can run only in restricted mode.

Ad Hoc Process Definitions

If your workflow process is truly ad hoc, then the user decides how a document should be routed for review when the user saves the document. You implement this type of ActionTable by setting the http://schemas.microsoft.com/cdo/workflow/adhocflows property on the OnSyncSave registration item in the workflow folder. Ad hoc workflows can run only in restricted mode.

Related Topics

  • ProcessDefinition Property
  • ProcessDefinitionURL Property

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Concepts and Architecture

This section does not currently contain any topics. Information will be provided here as it becomes available.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Programming Tasks

The topics in this section describe how to develop, test, and deploy applications that manage workflow, and workflow event sinks.

Developing Workflow Event Sinks

Developing Applications That Manage Workflow

Testing and Debugging Event Sinks and Applications That Manage Workflow

Deploying Event Sinks and Applications That Manage Workflow

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Developing Workflow Event Sinks

This section describes how to develop a workflow event sink.

Using the WorkflowSession Object

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Using the WorkflowSession Object

The typical workflow application developer implements business logic by using the WorkflowSession object. This object provides access to the workflow item and messaging without requiring that the developer have object creation privileges. The developer does not need to create this object, because the workflow engine passes the WorkflowSession object to the script host. Scripts can immediately call WorkflowSession methods and properties by using the object name. There is only one WorkflowSession object per transition, and that is the one the workflow engine passes to the script host. For restricted workflow authors, this is the only object they need to work with. Privileged workflow authors can create other objects in the script.

The typical workflow developer also uses the Microsoft® Exchange 2000 Server Workflow Designer. The Exchange Workflow Designer enables the developer to create a graphic representation of the workflow. The developer adds script conditions and actions to the graphic representation to create the rules for the workflow. See the Workflow Designer documentation for information about how to use this tool.

The following topics explain some of the things you can do with the WorkflowSession object:

Managing Run-Time Errors

Caching Custom Properties

Accessing Active Directory Properties

Using WorkflowSession Item Security

Using Audit Trail

Deleting Workflow Items

Working with ReceivedMessage

Accessing and Modifying a ProcessInstance

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Managing Run-Time Errors

To log a run-time error, set the IWorkflowSession ErrorNumber property to a negative value in your script. You can use decimal or hexadecimal notation, such as –2147467259 or &H80004005. When the workflow engine sees a negative value in the ErrorNumber property, it writes an error message to the audit trail. The workflow engine gets the message from the ErrorDescription property. The ErrorDescription property should contain the string that you want written to the audit trail for the associated error number.

For example, if the call to CreateObject fails in the following code, the workflow state-transition ends; this happens because you set the WorkflowSession ErrorNumber to a negative value. The workflow engine generates an entry in the application log of the event viewer with the error message that reads in part: State transition error: Error in action: I'm testing this. Note that the rest of the code in the procedure is executed, and any other procedure calls in the current action field are completed.

VBScript

   on error resume next
   Dim fso
   Set fso = CreateObject("Scripting.FileSystemObject")
   if err.number <> 0 then
      with WorkflowSession
         .ErrorNumber = &H80004005  ' (-2147467259)
         .ErrorDescription = "I'm testing this..."
      end with
   end if

'Message generated in Application log of Event Viewer:
' "State transition error: Error in action: I'm testing this..."

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Caching Custom Properties

You can make custom properties available from one script function to the next by caching your custom properties. There are two main scenarios where this feature is useful:

  • During any OnChange transition, the workflow engine looks for matching OnExit and OnEnter rules in the ActionTable. The workflow engine evaluates the conditions and actions for each rule in a predetermined evaluation order. You can cache custom properties during the entire OnChange transition, so that they can be used by any condition or action scripts.
  • An OnChange transition from a given state, for example state A, can have many possible outcomes. The outcomes in this example are state B, state C, state D, and so on. Each path from A to the respective outcome states — B, C, D, and so on — has conditions that must be tested. These conditions can contain functions that impair server performance if they are repeated too many times. After running the function one time, you can cache the result, so that subsequent condition scripts can use it without having to call the function.

You can cache your own properties for the duration of one transition. Use the IWorkflowSession Properties property to cache your custom properties. In the following example, the OnExit action caches a custom property. The custom property is used in the OnChange action, the OnEnter condition, and the OnEnter action. The OnEnter action completes the transition and is the last place the cached custom property can be used.

VBScript

''''''''
'EventType: OnExit
'Condition Expression:
True
'Action Script Procedure:
Dim oItem
Set oItem = CreateObject("CDO.Item")
'do something with oItem
WorkflowSession.Properties.Put "CustomPropertyName", oItem
''''''''
'EventType: OnChange
'Condition Expression:
   True
'Action Script Procedure
   dim MyCustomProperty
   Set MyCustomProperty = CreateObject("CDO.Item")
   Set MyCustomProperty = WorkflowSession.Properties.Get("CustomPropertyName")
   ProcedureThatUses MyCustomProperty
''''''''
'EventType: OnEnter
'Condition Expression:
   UseCustomProperty(WorkflowSession.Properties.Get("CustomPropertyName"))
'Action Script Procedure
   Dim MyCustomProperty
   Set MyCustomProperty = CreateObject("CDO.Item")
   Set MyCustomProperty = WorkflowSession.Properties.Get("CustomPropertyName")
   ProcedureThatUses MyCustomProperty
''''''''
'Shared Script:
Function UseCustomProperty(CustomPropertyValue)
   'do something with CustomPropertyValue
   UseCustomProperty = True
End Function

Sub ProcedureThatUses(varProp)
    'do something with varProp
end sub

A transition may include a compensating action. Compensating actions are called if your transition is aborted for any reason. However, you cannot use custom properties in a compensating action, because the Properties property is not available to compensating actions.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Accessing Active Directory Properties

The Microsoft® Active Directory™ directory service in Microsoft® Windows® 2000 contains information about users, groups, organizations, and services in your enterprise. You can locate Active Directory information by querying for properties of an Active Directory object. You can access Active Directory properties with the GetUserProperty method of the IWorkflowSession Interface. For example, a user may submit a form to a workflow-enabled folder. You may want the workflow to notify the user's manager when a new form is submitted. One way to obtain the manager's e-mail address is to look it up in Active Directory by using the manager property of the user object. The following code gets the e-mail address for the manager of the user who submitted the form. The code first gets the distinguished name of the manager from Active Directory, and then it uses the manager's distinguished name (DN) to get the manager's e-mail address.

VBScript

'Action Script Procedure:
mgr = GetUserMgr(WorkflowSession.Sender)

'Shared Script:
Function GetUserMgr(UserAddress)
   with WorkflowSession
      mgrDN = .GetUserProperty(UserAddress, "manager", 0) '0 = cdowfUserEmailAddress
      GetUserMgr = .GetUserProperty(mgrDN, "mail", 1) '1 = cdowfDistinguishedName
   end with
End Function

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Using WorkflowSession Item Security

You can control access to individual workflow items using IWorkflowSession, ItemAuthors, and ItemReaders collections. You populate these collections with either e-mail addresses or folder roles.

ItemAuthors

You can allow individual users, groups, or roles to modify and delete specific workflow items by using the ItemAuthors collection. Adding a user, group, or role to the collection gives exclusive Author access to the item. To add a user to the ItemAuthors collection, use the following code:

VBScript

'In Action field:
AddAuthor "someone@microsoft.com", 0 'MemberType=cdowfEmailAddress

'In Shared Script
Sub AddAuthor(MbrName,MbrType)
   WorkflowSession.ItemAuthors.Add MbrName, MbrType
End Sub

To delete this user from the ItemAuthors collection, use the following code:

VBScript

'In Action field:
DeleteAuthor "someone@microsoft.com"

'In Shared Script
Sub DeleteAuthor(MbrName)
   WorkflowSession.ItemAuthors.Delete mbrname
End Sub

To clear the ItemAuthors collection, use the following code:

VBScript

WorkflowSession.ItemAuthors.Clear

The following code writes the list of ItemAuthors to the audit trail and enumerates the members of the ItemAuthors collection:

VBScript

'In the Action field:
WriteAuthorsToAudit

'In the Shared Script:
Sub WriteAuthorsToAudit()
   Dim str
   Dim mbr
   str = vbcrlf
   with WorkflowSession
      for each mbr in .ItemAuthors
         str = str & .ItemAuthors(mbr) & vbcrlf
      next
      .AddAuditEntry str
   end with
End Sub

ItemReaders

You can give a collection of users or roles exclusive read access to specific workflow items by using the ItemReaders property. If you are not a member of ItemReaders:

  • The item will not appear in any of your views, folders, or queries.
  • You cannot open the item even if you know the URL.

To add a user to the ItemReaders collection, use the following code:

VBScript

'In Action field:
AddReader "someone@microsoft.com", 0 'MemberType=cdowfEmailAddress

'In Shared Script
Sub AddReader(MbrName,MbrType)
   WorkflowSession.ItemReaders.Add MbrName, MbrType
End Sub

VBScript

To delete this user from the ItemReaders collection, use the following code:

'In Action field:
DeleteReader "someone@microsoft.com"

'In Shared Script
Sub DeleteReader(MbrName)
   WorkflowSession.ItemReaders.Delete mbrname
End Sub

VBScript

To clear the ItemReaders collection, use the following code:

WorkflowSession.ItemReaders.Clear

The following code writes the list of ItemReaders to the audit trail and enumerates the members of the ItemReaders collection:

VBScript

'In the Action field:
WriteReadersToAudit

'In the Shared Script:
Sub WriteReadersToAudit()
   Dim str
   Dim mbr
   str = vbcrlf
   with WorkflowSession
      for each mbr in .ItemReaders
         str = str & .ItemReaders(mbr) & vbcrlf
      next
      .AddAuditEntry str
   end with
End Sub

In the next example, you want to give a user's manager exclusive read privileges on an item. The following code demonstrates how to give the user's manager author and read permission.

VBScript

'Action Script Procedure:
ManagerLockOut

'Shared Script:
Sub ManagerLockOut()
   Dim str
   with WorkflowSession
      str = GetUserMgr(.Sender)
      .ItemAuthors.Add str,0 'cdowfEmailAddress
      .ItemReaders.Clear
      .ItemReaders.Add str,0 'cdowfEmailAddress
   end with
End Sub

Function GetUserMgr(UserAddress)
   with WorkflowSession
      mgrDN = .GetUserProperty(UserAddress, "manager", 0) '0 = cdowfUserEmailAddress
      GetUserMgr = .GetUserProperty(mgrDN, "mail", 1) '1 = cdowfDistinguishedName
   end with
End Function

Notice that the ManagerLockOut procedure clears the ItemReaders collection before adding the manager to the ItemReaders collection. This makes the manager the only member of the collection, thus giving the manager exclusive read access to the item.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Using Audit Trail

You can use the audit trail for logging custom messages during script execution. This can be useful as a debugging tool. Use the IWorkflowSession AddAuditEntry to log messages to the current audit trail provider.

The following code builds a debug string that is entered in the log when the script runs:

VBScript

Sub SendAuditedMail (MySubject)
   Dim strDebug
   strDebug = vbCrLf
   set WFMsg = WorkflowSession.GetNewWorkflowMessage()
   with WFMsg
      .From = WorkflowSession.Sender
      .To = "someone@microsoft.com"
      .Subject = MySubject
      .TextBody = WorkflowSession.StateFrom & " -> " & WorkflowSession.StateTo
      .SendWorkflowMessage 0 'cdowfNoTracking
      strDebug = strDebug & _
                 "From: " & .from & "; " & _
                 "To: " & .to & "; " & _
                 "Subject: " & .subject & "; " & _
                 "TextBody: " & .textbody & "."
   end with
   WorkflowSession.AddAuditEntry strDebug
End Sub

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Deleting Workflow Items

You can delete a workflow item during any transition, except during OnReceive events, by using the IWorkflowSession DeleteWorkflowItem method. Deleting a workflow item during a transition will not raise an OnDelete event. If you want to take special delete action, do it in the same script in which you use the DeleteWorkflowItem method.

You can use the following code in an action or condition script:

VBScript

WorkflowSession.DeleteWorkflowItem

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Working with ReceivedMessage

In workflow, a ReceivedMessage is a reply posted to a folder as part of an existing workflow process. You receive the reply in response to an e-mail initiated by the workflow process. These replies contain information necessary to advance the workflow. The ReceivedMessage property of the IWorkflowSession Interface returns the IWorkflowMessage Interface of a reply to an e-mail sent using the SendWorkflowMessage method. The ReceivedMessage property is available only in an OnReceive event. This is known as e-mail workflow and is used in a situation where users do not have a direct connection to the corporate network and Web Storage System.

In e-mail workflow, you use the IWorkflowMessage Interface with the SendWorkflowMessage method to send e-mail whose reply can be matched with an existing workflow process. Use the GetNewWorkflowMessage method to get an IWorkflowMessage Interface. SendWorkflowMessage adds two fields to the message that are used to match a reply with an existing workflow process. The following two fields are added by SendWorkflowMessage:

  • http://schemas.microsoft.com/cdo/workflow/workflowmessageid
  • http://schemas.microsoft.com/cdo/workflow/parentprocinstance

These two fields and values must be properties of the reply form. They are required in the reply form so that the workflow engine can correlate the reply to the original workflow process and item. When the workflow engine matches a reply, the ReceivedMessage property contains the IWorkflowMessage Interface in the reply. You can access and modify the Fields collection of the reply to advance the workflow.

In the following code, SendWorkflowMessage creates and populates the workflowmessageid and parentprocinstance fields on the message that it sends. When the client, such as Microsoft® Outlook®, receives the message, a macro embedded in MyForm copies the values from the fields on the message to fields of the same name on the reply. When the workflow engine handles the reply from the client form, it correlates the reply to the original item based on workflowmessageid and parentprocinstance fields. An OnReceive event triggers the UpdateWorkflowItem procedure, which consolidates the message body into a TrackingTable field.

If you want to track responses — for example, voting — do the following:

  • Make sure your form contains the field http://schemas.microsoft.com/cdo/workflow/response.
  • Make sure you bind the form control containing the response data to the http://schemas.microsoft.com/cdo/workflow/response field on the form.

If your form contains the field http://schemas.microsoft.com/cdo/workflow/response, the workflow engine writes the value of this field to the response field of the TrackingTable. Response tracking is automatic and requires no coding on your part.

The code in the following example assumes that you have created and published a form in Outlook called MyForm with the workflowmessageid and parentprocinstance properties.

VBScript

'In Form script for MyForm:
Sub Item_Reply(ByVal Response)
   set CurrentProp = Response.UserProperties.Add( "http://schemas.microsoft.com/cdo/workflow/parentprocinstance", 1)
   CurrentProp.Value = Item.UserProperties("http://schemas.microsoft.com/cdo/workflow/parentprocinstance").Value
   set CurrentProp = Response.UserProperties.Add ("http://schemas.microsoft.com/cdo/workflow/workflowmessageid", 1)
   CurrentProp.Value = Item.UserProperties("http://schemas.microsoft.com/cdo/workflow/workflowmessageid").Value
End Sub

'EventType: OnChange (original workflow item)
'Action Script Procedure::
SendWorkflowItem 2 '"cdowfStrict"

'EventType: OnReceive (reply to sendworkflowitem)
'Action Script Procedure:
UpdateWorkflowItem

'In Shared Script:
Sub SendWorkflowItem(cdowfMethod)
      Set WFMsg = WorkflowSession.GetNewWorkflowMessage
      with WFMsg
         .To = WorkflowSession.Sender
         .Subject = "Workflow Item"
         .TextBody = "Workflow Item body"
         .Fields("http://schemas.microsoft.com/mapi/proptag/0x001A001E").Value = "IPM.Note.MyForm"
         .Fields.Update
         .SendWorkflowMessage cdowfMethod
      end with
End Sub

Sub UpdateWorkflowItem()
   with WorkflowSession
      .TrackingTable.Fields("custom0") = .TrackingTable.Fields("custom0") & vbCrLf & _
                                                               .ReceivedMessage.TextBody
      .TrackingTable.Fields.Update
   end with
End Sub

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Accessing and Modifying a ProcessInstance

A ProcessInstance is an individual workflow item in a Microsoft Web Storage System folder. You can access and modify properties of a ProcessInstance with the Fields collection of the IWorkflowSession interface. The workflow engine provides the IWorkflowSession object to the script host without you having to do anything. The following code illustrates how to access a field by using the field name as an index to the Fields collection on the IWorkflowSession Interface.

VBScript

Function GetFieldValue(Name)
   GetFieldValue = WorkflowSession.Fields(CStr(Name)).Value
End Function

The Fields collection also enables you to append new fields to a ProcessInstance. Use the Append method of the Fields collection, as shown in the following example:

VBScript

Sub AddFieldToItem (Name, Value)
   Dim FieldType
   FieldType = 8 ' BSTR
   with WorkflowSession
      .Fields.Append CStr(Name), FieldType, , , CStr(Value)
      .Fields.Update
   end with
End Sub

You may decide to send notification with a different subject depending on the importance flag of a ProcessInstance. You can use the Fields collection of the IWorkflowSession Interface to obtain the value for the urn:schemas:httpmail:importance property on the item. The following code shows the action script that calls shared scripts in Microsoft® Exchange Workflow Designer.

VBScript

'This goes in the action pane of Workflow Designer
dim x
x = GetImportance()
if x=2 then 'High Importance
   SendMail "Alert!"
else 'Normal or Low Importance
   SendMail "At ease."
end if

'These go on the Shared Script tab
Function GetImportance()
   GetImportance = WorkflowSession.Fields("urn:schemas:httpmail:importance").Value
End Function

Sub SendMail(MySubject)
   Set WFMsg = WorkflowSession.GetNewWorkflowMessage()
   With WFMsg
      .From = WorkflowSession.Sender
      .To = GetUserMgr(WorkflowSession.Sender)
      .Subject = MySubject
      .TextBody = WorkflowSession.StateFrom & " -> " & WorkflowSession.StateTo
      .SendWorkflowMessage 0 'cdowfNoTracking
   End With
End Sub

Function GetUserMgr(UserAddress)
   with WorkflowSession
      mgrDN = .GetUserProperty(UserAddress, "manager", 0) '0 = cdowfUserEmailAddress
      GetUserMgr = .GetUserProperty(mgrDN, "mail", 1) '1 = cdowfDistinguishedName
   end with
End Function

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Developing Applications That Manage Workflow

The topics in this section describe how to develop applications that manage workflow.

Creating Workflow Action Tables

Creating the ProcessDefinition

Controlling Workflow Management Access with Security Modes

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Creating Workflow Action Tables

Advanced developers may want to write their own event sink or Workflow Designer. This section contains examples of the fundamental tasks involved in writing an event sink or Workflow Designer. These tasks include:

Creating ActionTable Columns

Adding ActionTable Rows

Specifying the Common Script File

Creating the ProcessDefinition

Registering a Workflow Event Sink in a Folder

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Creating ActionTable Columns

Creating action table columns is the first step in creating an action table for a workflow.

In workflow terms, an action table is a set of rules that define how workflow items can change state. Each row in the table represents a possible state transition in the workflow. In an expense report example, one row in the table defines how an item gets from the submitted state to the pending state. Another row defines how an item gets from the pending state to the approved state. The columns in an action table define the properties that the workflow engine uses to advance a workflow.

In programming terms, an action table is a record set. To create an action table, you create a Microsoft® ActiveX® Data Objects (ADO) database (ADODB) record set. You begin by appending Fields to the Fields collection of a new Recordset object. You append Fields before opening the Recordset object or a Connection object. The workflow engine requires and recognizes fourteen fields exclusively. In the Append method, you provide the field name and type as arguments. The following example shows how to append the action table fields to a Recordset object.

Visual Basic

   Dim Rs As ADODB.Recordset
   Set Rs = New ADODB.Recordset

   With Rs.Fields
    .Append "ID", adBSTR
    .Append "Caption", adBSTR
    .Append "State", adBSTR
    .Append "NewState", adBSTR
    .Append "EventType", adBSTR
    .Append "Condition", adBSTR
    .Append "EvaluationOrder", adBSTR
    .Append "Action", adBSTR
    .Append "ExpiryInterval", adBSTR
    .Append "RowACL", adBSTR
    .Append "TransitionACL", adBSTR
    .Append "DesignToolFields", adBSTR
    .Append "CompensatingAction", adBSTR
    .Append "Flags", adBSTR
   End With

   Dim varColumnNames As Variant

   varColumnNames = Array(Rs.Fields.Item(0).Name, _
                         Rs.Fields.Item(1).Name, _
                         Rs.Fields.Item(2).Name, _
                         Rs.Fields.Item(3).Name, _
                         Rs.Fields.Item(4).Name, _
                         Rs.Fields.Item(5).Name, _
                         Rs.Fields.Item(6).Name, _
                         Rs.Fields.Item(7).Name, _
                         Rs.Fields.Item(8).Name, _
                         Rs.Fields.Item(9).Name, _
                         Rs.Fields.Item(10).Name, _
                         Rs.Fields.Item(11).Name, _
                         Rs.Fields.Item(12).Name, _
                         Rs.Fields.Item(13).Name)

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Adding ActionTable Rows

After you have a record set with the columns required by the workflow engine, you can begin adding records. To do this, you first open the record set with the fields previously appended, then use the AddNew method to add records. After you have added your records to the record set, you can assign the Recordset object to the ActionTable property of the ProcessDefinition.

Visual Basic

   Rs.Open
   If Err.Number <> 0 Then
      Debug.Print "Failed to open ActionTable Recordset" & Err.Description
   End If

   With Rs
    .AddNew varColumnNames, Array("1", "OnCreate", "", "Submitted", "OnCreate", "true", "", "sendmail(""new ProcessInstance"")", "", "", "", "", "", "0")
    .AddNew varColumnNames, Array("2", "OnEnter", "", "Submitted", "OnEnter", "true", "", "sendmail(""entered submitted state"")", "", "", "", "", "", "0")
    .AddNew varColumnNames, Array("3", "OnExpiry", "Submitted", "Submitted", "OnExpiry", "true", "", "sendmail(""submitted state expired"")", "", "", "", "", "", "0")
    .AddNew varColumnNames, Array("4", "OnDelete", "Submitted", "", "OnDelete", "true", "", "sendmail(""deleted ProcessInstance"")", "", "", "", "", "", "0")
   End With

For an example of how to append fields to a record set before adding records, see Creating Action Table Columns. For a more detailed explanation of working with Record and Recordset objects, see the Microsoft® ActiveX® Data Objects (ADO) topic in the MSDN® Library Platform SDK, Data Access Services, Microsoft Data Access Components (MDAC).

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Specifying the Common Script File

The common script file is a text document containing script functions that you can share among many workflow applications. To specify the common script file, you can:

  • Use the CommonScriptURL property of the IProcessDefinition Interface.
  • Load the common script text as the default Stream property of the ProcessDefinition item.

The following code shows how to load the common script as the default Stream property of the ProcessDefinition item.

Note You must set the Charset property of the Stream to Unicode.

Visual Basic

   Dim fso As New Scripting.FileSystemObject
   Dim file1 As TextStream

   Set file1 = fso.OpenTextFile(cstPath)

   Dim commonscripttext As String
   commonscripttext = file1.ReadAll

   Dim Rec As New ADODB.Record
   Dim Conn As New ADODB.Connection
   Dim Stm As New ADODB.Stream

   With Conn
      .Provider = "Exoledb.datasource"
      .ConnectionString = wfFolder
      .Open
   End With

   Rec.Open pdURL, Conn, adModeReadWrite, adCreateOverwrite

   With Stm
      .Open Rec, adModeReadWrite, adOpenStreamFromRecord
      .Charset = "unicode"
      .Type = adTypeText
      .Position = 0
      .SetEOS
      .WriteText commonscripttext
      .Position = 0
      .Flush
      .Close
   End With

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Creating the ProcessDefinition

The ProcessDefinition object encapsulates your business logic and defines how the workflow engine will advance a workflow item. The ProcessDefinition object also determines which privileges your scripts have and which audit trail provider the workflow engine uses.

The following code shows how to create a new ProcessDefinition object and an ActiveX Data Objects (ADO) Connection. The code binds to the target Web Storage System folder with a Connection object. With the open connection, it sets the desired properties on the ProcessDefinition object. Then it uses the Recordset object that was built at run time and sets the ActionTable property on the ProcessDefinition object. (See Creating ActionTable Columns and Adding ActionTable Rows for examples of how to create the action table record set.) Finally, it saves the ProcessDefinition properties to the URLs and commits the transaction.

The following topics provide more information about creating ProcessDefinitions:

Workflow Process Definition

Registering a Workflow Event Sink in a Folder

Visual Basic

Note The following example uses a file URL with the Exchange OLE DB (ExOLEDB) provider. The ExOLEDB provider also supports the HTTP URL scheme. Using the HTTP URL scheme allows both client and server applications to use a single URL scheme.
   Dim iPD As New CDOWF.ProcessDefinition
   Dim conn As New ADODB.Connection

   sDomainURL = "file://./backofficestorage/" _
                & Environ("USERDNSDOMAIN") & _
                "/Public Folders/"
   sFolderURL = sDomainURL & sFolderName
   sProcDefURL = sFolderURL & "/" & sProcDef

   conn.Provider = "ExOleDb.DataSource"
   conn.Open sFolderURL
   conn.BeginTrans

   With iPD
    .ActionTable = Rs
   'Rs is an open ADODB.Recordset built at run time

    .AuditTrailProvider = "CdoWf.AuditTrailEventLog"
    .CommonScriptURL = sCommonScriptURL
    .Mode = cdowfPrivilegedMode
    .Fields("DAV:ishidden") = True
   End With

   iPD.DataSource.SaveTo sProcDefURL, _
                         conn, _
                         adModeReadWrite, _
                         adCreateOverwrite Or adCreateNonCollection

   conn.CommitTrans

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Workflow Process Definition

The workflow process definition is the design that you create to control the flow of documents in your workflow folder. If you are using the Microsoft® Exchange 2000 Server Workflow Designer, the process definition is generated automatically from the diagram and script code that you create. Advanced developers can use the ProcessDefinition object directly in Active Server Pages (ASP) applications and middle-tier components. The ProcessDefinition object encapsulates the business logic in its ActionTable property and specifies which script file to use for conditions and actions that are executed at run time. In addition, you specify the security mode for your workflow and how you want to audit workflow processes.

This section includes the following topics:

Defining the ActionTable

Setting Security and Audit Properties

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Defining the ActionTable

The ActionTable is an ActiveX Data Objects (ADO) recordset stored as a property of the ProcessDefinition object. The action table distills your business rules into a list of possible state transitions. Microsoft® Exchange Web Storage System events drive a workflow tracking process with Collaboration Data Objects (CDO) workflow objects. The workflow engine provides a systematic process to control state transitions for documents in the Web Storage System. The workflow engine relies on a table of actions (called the ActionTable), defined by the workflow process designer, to evaluate and execute transitions for documents saved in the action application folder. The following table illustrates a simplified subset of a typical row in an action table. A complete row in the ActionTable includes fourteen fields.

Row ID | Caption | State | NewState | EventType | Condition | Action
"1" | "Create" | "" | "Submitted" | "OnCreate" | "IsValidExpenseForm()" | "CheckDollarAmount"

The following table illustrates a variety of actions that could be specified in an action table.

State | NewState | EventType | Condition | Action | ExpiryInterval
"" | "Initial" | "OnCreate" | "IsValid()" | "SendMail(Mgr)" |
"Initial" | "Assigned" | "OnChange" | "IsDelegated()" | "SendMail(Worker)" |
"" | "Assigned" | "OnEnter" | "True" |  | "15"
"Assigned" | "Completed" | "OnChange" | "IsBalanced()" | "TimeStamp() SendMail(Mgr)" |
"Completed" | "" | "OnDelete" | "HasTimeStamp()" | "Archive()" |
"Initial" | "" | "OnExit" | "True" | "MarkInitialized()" |

The following sections describe how to use the action table.

Row Evaluation Order

Event Types

Conditions and Actions

Related Topics

  • ActionTable Property

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Row Evaluation Order

When the workflow engine finds more than one match for a single state-transition, it evaluates action table rows in a clearly defined order. The following table shows two rows from a larger action table. The workflow engine matches both rows 4 and 5 when a document is saved in the workflow folder for the first time.

ID | Event | CurrentState | NewState | Condition | Action | ExpiryInterval
4 | OnCreate | "" | Submitted | True | NotifyMgr() |
5 | OnEnter | "" | Submitted | True |  | 15 minutes

In the example illustrated in the preceding table, the workflow engine follows this order:

  1. Matches the OnCreate row first and executes its action.
  2. Matches the OnEnter event and executes its action.

The workflow engine obeys the following rules in all cases:

  1. Looks for an OnChange row to match the current state and next state fields.
  2. Finds an OnChange row match and looks for an OnExit row match.
  3. Finds an OnExit row match and executes the OnExit action.
  4. After executing the OnExit action, executes the OnChange action.
  5. Looks for an OnEnter row to match. If it finds a matching OnEnter row, it executes its action script.

The following two tables illustrate the evaluation rules for all cases. The first table represents an action table with symbols for the different states, conditions, and actions. The second table shows the order in which the workflow engine performs the actions.

Event | State | Condition | Action | NewState
OnChange | A | X | I | B
OnExit | A | Y | II |
OnEnter |  | Z | III | B

Given the preceding table, the following order applies:

Order | Condition/Script
1st | Condition X returns true
2nd | Evaluate condition Y
3rd | Evaluate action II
4th | Evaluate action I
5th | Evaluate condition Z
6th | Evaluate action III

The ActionTable includes an EvaluationOrder column for making clear decisions about multiple matching rows during a single document transition. If this column is blank, no order is guaranteed when more than one row matches.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Event Types

There are two sets of event types in workflow.

  • The workflow event sink uses the CdoWfEventType Enum when it calls the Advance method of the IProcessInstance Interface.
  • The ActionTable uses event types to characterize document transitions.

Using CdoWfEventTypes in Calls to Advance

If you develop your own event sink to use with the workflow engine, use the following CdoWfEventTypes.

  • cdowfOnCreate
  • cdowfOnChange
  • cdowfOnDelete
  • cdowfOnExpiry
  • cdowfOnReceive

Using Event Types with an Action Table

Use event types when you design the ActionTable to define which event you want a rule to fire for. Your ActionTable can include states that have more than one path of entry or exit. You might take certain actions with a workflow item regardless of how it reached a given state. When you want an action to fire for a particular state, no matter how the ProcessInstance entered or exited that state, the ActionTable event types include two types for you to use. OnEnter and OnExit allow you to specify an action for a given state whenever a ProcessInstance enters or leaves that state. The following table lists the values that you can use in the ActionTable EventType field.

Name | Value | Description
OnCreate | 1 | Document was created.
OnChange | 2 | Document was modified.
OnDelete | 3 | Document was deleted.
OnEnter | 4 | New state is entered. This is where the Microsoft® Exchange Workflow Designer usually sets the expiry interval.
OnExit | 5 | Old state is exited.
OnExpiry | 6 | Document has been in the current state too long.
OnReceive | 7 | Received an e-mail response correlating to the document.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Conditions and Actions

Conditions and Actions are scripts or Component Object Model (COM) objects that implement your business logic. These scripts are contained in the following action table fields:

  • Condition
  • Action
  • Compensating Action

The preceding fields can contain inline script, calls to script functions in a global script file, or the ProgIDs of custom (COM) objects. You use action table row entries to indicate to the workflow engine what combination of scripts and objects to use, by setting the flags in the last column of the action table row. The Flags field represents a binary OR'd value of CdoWfTransitionFlags constants. The following table shows the possible combinations.

Flag Value | Condition | Action | CompensatingAction
0x00 | Script | Script | Script
0x01 | Script | Object | Script
0x02 | Object | Script | Script
0x03 | Object | Object | Script
0x04 | Script | Script | Object
0x05 | Script | Object | Object
0x06 | Object | Script | Object
0x07 | Object | Object | Object
Note In most cases, the condition field should not be empty. If you leave the field empty, and you use the ProcessDefinition object to define your workflow, you will receive an error when the ProcessDefinition validates the ActionTable. Also, the workflow engine must find at least one TRUE condition per state and event type in your ActionTable, otherwise it returns the CDOWF_NO_CONDS_MATCHED failure code.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Setting Security and Audit Properties

The following sections provide information and links for learning about setting workflow security modes and audit history providers.

Setting the Security Mode

You use the ProcessDefinition object to set the security mode for the workflow. The IProcessDefinition Interface has a mode property that tells the workflow engine the mode in which you want the workflow to execute. In restricted mode, you are not able to use Component Object Model (COM) objects in the ActionTable, or to create objects in memory from script. In privileged mode, you can use COM objects in the ActionTable and coCreate almost any object in script. If you do not set the mode property, it defaults to zero (0). Zero is neither restricted nor privileged. Your application will not run with a zero value for the mode property. You must explicitly set the security mode. Security modes are covered in more detail in Controlling Workflow Management Access with Security Modes.

The Workflow System Account needs to have sufficient privileges in the workflow folder. If you register events for the workflow folder, provide at least read privileges. If the event sinks will make changes to the folder contents, the Workflow System Account requires read and write privileges in the folder.

Setting the Audit Trail Provider

You also use the ProcessDefinition object to tell the workflow engine what tool to use for logging information, warnings, and error messages. These messages are useful for monitoring and debugging your workflow application. The default audit trail provider that comes with Microsoft® Exchange 2000 Server writes all auditing information to the Microsoft® Windows® 2000 event log.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Registering a Workflow Event Sink in a Folder

The workflow event sink handles OnSyncSave, OnSyncDelete, and OnTimer events in any Web Storage System folder where it is registered. When a user saves or deletes an item in a folder, an event occurs. When the event occurs in a folder, the Web Storage System process looks for an event registration item in the folder. The registration item tells the Web Storage System which process handles the event. You need to tell the Web Storage System that you want the workflow event sink process to handle OnSyncSave, OnSyncDelete, and OnTimer events in your folder. This is called registering the workflow event sink in a folder.

The following rules govern the registration of an event sink:

  • The event type must be one of the three supported types: OnSyncSave, OnSyncDelete, or OnTimer.
  • The user who registers the workflow must be a member of the Can Register Workflow role. Deploying Event Sinks and Applications That Manage Workflow explains how to do this.
  • The Workflow System Account must have at least read privileges in the folder. Events that must make changes to the folder contents require that the Workflow System Account have both read and write privileges in the folder.
  • You cannot set the MatchScope Field of the registration to ANY.
  • You cannot register the event sink for a synchronous event with the DEEP MatchScope Field if it is already registered in a subfolder of the same folder.
  • You cannot register the event sink in a folder where it is already registered by a DEEP MatchScope Field registration in a parent folder.
  • When you set the OnTimer interval, it should not be smaller than necessary, because the OnTimer event occurs for every workflow folder on the server.
  • OnTimer events can have DEEP MatchScope Field only on a public folder tree that you create. DEEP MatchScope Field for OnTimer events is not supported in the default public folder tree.
Note The store event registrations set the criteria field with an SQL WHERE clause to prevent other registrations, ProcessDefinitions, and CommonScripts from raising events in the folder.

The following code registers your workflow application folder for the OnTimer system event, the OnSyncSave store event, and the OnSyncDelete store event. In this example, the OnTimer event causes the workflow event sink to run every 15 minutes.

Visual Basic

  Dim EventRuleItem As String
  Dim sEvtRegURL As String
  Dim ProcessDefinitionURL As String

'''''''''''''''''''''Register OnTimer Event

  EventRuleItem = "OnTimerRule"

  sEvtRegURL = sFolderURL & EventRuleItem

  'The event registration item (sEvtRegURL) must be saved
  'in the folder for which you want to register
  'the workflow sink.

  Dim Rec As ADODB.Record
  Set Rec = New ADODB.Record

  Rec.Open sEvtRegURL, , adModeReadWrite, _
                       adCreateNonCollection Or adCreateOverwrite, _
                       adDelayFetchFields
  If Err.Number <> 0 Then
     Debug.Print "Failed to open event registration record." & Err.Description
  End If

  Dim Flds As ADODB.Fields
  With Rec
    Set Flds = .Fields
    Flds("DAV:contentclass") = "urn:content-class:storeeventreg"
    Flds("http://schemas.microsoft.com/exchange/events/EventMethod") = "OnTimer"
    Flds("http://schemas.microsoft.com/exchange/events/SinkClass") = "CdoWfEvt.EventSink.1"
    Flds("http://schemas.microsoft.com/exchange/events/TimerStartTime") = #5/1/1999#
    Flds("http://schemas.microsoft.com/exchange/events/TimerInterval") = 720
    Flds("http://schemas.microsoft.com/exchange/events/TimerExpiryTime") = #8/4/2000#
    Flds.Update
    .Close
  End With

'''''''''''''''''''''Register OnSyncSave and OnSyncDelete Events

  EventRuleItem = "OnSyncSave_OnSyncDelete_Rule"

  sEvtRegURL = sFolderURL & EventRuleItem

  ProcessDefinitionURL = sProcDefURL

  Rec.Open sEvtRegURL, , adModeReadWrite, _
                       adCreateNonCollection Or adCreateOverwrite, _
                       adDelayFetchFields
  If Err.Number <> 0 Then
     Debug.Print "Failed to open event registration record." & Err.Description
  End If

  With Rec
    Set Flds = .Fields
    Flds("DAV:contentclass") = "urn:content-class:storeeventreg"
    Flds("http://schemas.microsoft.com/exchange/events/EventMethod") = "OnSyncSave;OnSyncDelete"
    Flds("http://schemas.microsoft.com/exchange/events/SinkClass") = "CdoWfEvt.EventSink.1"
    Flds("http://schemas.microsoft.com/exchange/events/Criteria") = "WHERE $DAV:ishidden$ AND $DAV:iscollection$ = FALSE"
    Flds("http://schemas.microsoft.com/cdo/workflow/defaultprocdefinition") = ProcessDefinitionURL
    Flds("http://schemas.microsoft.com/cdo/workflow/adhocflows") = 0
    Flds("http://schemas.microsoft.com/cdo/workflow/enabledebug") = True
    Flds("http://schemas.microsoft.com/cdo/workflow/disablesuccessentries") = False
    Flds.Update
    .Close
  End With

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Controlling Workflow Management Access with Security Modes

When your action table includes scripts and Component Object Model (COM) objects that run on your server, workflow security becomes a big issue. You can prevent workflow applications from disrupting your server by using workflow security modes. Use security modes to differentiate between trusted and non-trusted developers. Security modes provide users the most flexibility within appropriate limitations.

The following table summarizes the two security modes that you can implement with Collaboration Data Objects (CDO)

Factors to consider | Restricted mode | Privileged mode
Script access | Only the current Microsoft Web Storage System item ( ProcessInstance) is accessible. | Scripts and objects can access enterprise databases as security context allows.
Security context | Workflow System Account defined by the system administrator AND ActiveConnection of user who triggered workflow event
Cocreatable COM objects | None | Unlimited registered components. Allows you to integrate with other systems such as Structured Query Language (SQL) databases and other applications that provide COM components.
Microsoft® Active Directory™ access | Limited Active Directory lookups through the WorkflowSession GetUserProperty method. | Can use LDAP and Active Directory.

Use restricted mode for non-trusted workflows. Users should be free to set up one-off workflow designs to track documents, but you don't want them to be able to run any script or COM object.

The security mode is a property of the ProcessDefinition, which you set at design time. You can set this property to either restricted or privileged. For your workflow to run in privileged mode, however, you must be a member of the PrivilegedWorkflowAuthors COM+ role; this is checked by the Workflow Event Sink at run time. PrivilegedWorkflowAuthors is a COM+ role created by Microsoft® Exchange 2000 Server setup.

The following illustration shows Component Services in Microsoft Management Console (MMC), where you can view the workflow event sink COM+ package with the PrivilegedWorkflowAuthors role and its members.

Read Privilege Checking for additional details.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Privilege Checking

The Dynamic HTML (DHTML) workflow event sink enforces security by checking privileges at run time. The event sink performs this check to prevent an unauthorized person from tampering with the scripts, workflow process design, or other application data. For privileged mode workflows, it verifies that all the design-time pieces of a workflow were last modified by a member of the PrivilegedWorkflowAuthors role. This includes:

  • ProcessDefinition
  • CommonScript
  • Event Sink Registration

After checking privileges, the event sink calls Advance. The call to Advance fails if any of these were last modified by anyone other than a member of the PrivilegedWorkflowAuthors role.

Microsoft® Exchange 2000 Server Setup creates the Component Object Model (COM)+ application package for the workflow event sink and installs the PrivilegedWorkflowAuthors role.

Read these sections for details about the two security modes:

Restricted Mode

Privileged Mode

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Restricted Mode

Restricted mode is for non-trusted developers. This mode has a limited set of permissions and allows access only to the intrinsic WorkflowSession object. The following table summarizes restricted mode characteristics.

Feature | Description
Script execution only | The workflow conditions and action must be written in script. You cannot use Component Object Model (COM) objects in this mode.
Sandboxed script only | The workflow engine configures the script host to disallow the use of CreateObject. The script can modify the row undergoing the workflow using the IWorkflowSession Interface.
Script runs as Workflow System Account | The script host executes the script under the same Microsoft® Windows® 2000 security account as the caller. No impersonation occurs. In the default case for the Collaboration Data Objects (CDO) Workflow event sink, this means that the script will run in the Workflow System Account, which typically has full administrative permissions to most Microsoft® Exchange 2000 Server resources.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Privileged Mode

You can configure the workflow application to run in privileged mode. When it runs in privileged mode, the workflow engine verifies that your design-time objects are authored by someone with proper privileges. The following table summarizes the privileged mode characteristics.

Feature | Description
Script or Component Object Model (COM) actions | The workflow action can be either script or a call to a registered COM object.
No script sandboxing | The workflow engine allows the use of CreateObject for any valid classID on the system including the FileSystem object, all Collaboration Data Objects (CDO) or Microsoft® ActiveX® Data Objects (ADO) objects, and so on.
Script runs as Workflow System Account | The script host executes the script under the same Microsoft® Windows® 2000 security account as the caller. No impersonation occurs. In the default case for the CDO Workflow event sink, this means that the script will run in the Workflow System Account, which typically has full administrative permissions to most Microsoft® Exchange 2000 Server resources.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Testing and Debugging Event Sinks and Applications That Manage Workflow

Built-in workflow functionality enables you to test and debug a process design. You can use the audit trail to follow the success or failure of state transitions during the testing phase. In addition, you can enable the workflow engine to start the Microsoft Script Debugger when you get a script run-time error. The following sections describe these features.

Using an Audit Trail

Using Microsoft Script Debugger

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Using an Audit Trail

The workflow components include a built-in audit trail provider. The AuditTrailEventLog provider writes messages to the application log in the Microsoft® Windows® 2000 Event Viewer.

Collaboration Data Objects (CDO) workflow defines an IAuditTrail Interface that you can use to develop your own auditing tool. You can use any component that supports this interface as an audit trail logging tool. You specify the program identifier (ProgID) of your component in the AuditTrailProvider property of the ProcessDefinition object when you design the workflow application.

You can use the audit trail to gather information about where your process succeeded or failed. For example, it tells you whether the source of the audit event was the event sink or the workflow engine. It also records the nature of the transition, so that you can tell where the workflow item was in the process.

Sometimes you get run-time errors for which the audit trail cannot help you determine the cause. In those cases, you might need to debug the script code. The Using Microsoft Script Debugger section describes how the Script Debugger works with workflow.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Using Microsoft Script Debugger

Use Microsoft Script Debugger when you get unexpected results from a save or delete operation on the client. This usually means that your script caused a run-time exception. If you are using the Microsoft® Exchange Workflow Designer, you use a checkbox to enable Just-In-Time (JIT) script debugging. JIT starts Script Debugger when the error occurs. The debugger starts on the server, so you need to have access to the server. Developers creating their own tools can enable JIT using the Web Storage System schema property. To enable JIT script debugging, set enabledebug equal to true for the OnSyncSave and OnSyncDelete event registration items in the workflow folder. The workflow engine uses the value of this property with the EnableDebug method of the IProcessInstance interface to configure the script host before running any script.

For JIT to work correctly, the server environment must be set up properly. The following three requirements must be met:

  • The workflow event sink Component Object Model (COM)+ identity must be set to "interactive user" in component services.
  • The registry key "HKCU/Software/Microsoft/Windows Script/Settings/JITDebug" must be set to REG_DWORD "1".
  • If event sink is installed on the server, JIT must be enabled in Tools|Options|Debugger|General.
Note You may have to create the registry key.

By default a workflow script aborts after 15 minutes (900 seconds). You can configure the maximum time a script executes using the following registry key:

  • "HKLM\SOFTWARE\Microsoft\Exchange\Workflow\Maximum execution time for scripts in seconds"

Set this higher to allow more time to debug the script. Specify maximum time a script executes in seconds with a setting of type DWORD. You have to set this key on any computer that you want to configure the maximum time a script executes. You may be required to create the registry key.

Note The minimum supported setting is 5 minutes (300 seconds).

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Deploying Event Sinks and Applications That Manage Workflow

To manage the deployment of workflow processes and the deployment of tools for managing workflow, use the Microsoft® Active Directory™ Users and Computers console and the Components Services console. The following sections describe the steps involved in deploying workflow processes and applications that manage workflow.

Adding the Workflow System Account

Registering a Workflow Event Sink

Privileged Workflow Authors

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Adding the Workflow System Account

The workflow event sink will not run with proper privileges unless you add a Workflow System Account as a member of Exchange Domain Servers. To do this, use Microsoft® Active Directory™ Users and Computers and Active Directory Component Services. Microsoft® Exchange 2000 Server Setup installs workflow components by default.

To add the Workflow System Account, perform the following steps:

  1. Select an existing account from your Microsoft® Windows® 2000 domain or create a new account. These instructions assume that you have chosen an account named "Workflow System Account". Set the Workflow System Account password expiration policy to never expire.
  2. Check that the Workflow System Account has an Exchange mailbox. If the mailbox does not already exist, create it. If your application uses e-mail-based workflow (IWorkflowMessage Interface SendWorkflowMessage Method), the Workflow System Account mailbox folder must be on the same physical server as the application folder where you register the workflows. This restriction does not apply to workflows that use the IWorkflowMessage Interface Send Method, because IWorkflowMessage uses Simple Mail Transport Protocol (SMTP).
  3. Add the Workflow System Account to the Windows 2000 group named Domain EXServers. This enables the Collaboration Data Objects (CDO) workflow event sink to execute with proper privileges.
  4. In the console tree of Component Services, select your computer. Then select the Component Object Model (COM)+ application named Workflow Event Sink. On the Action menu, click Properties.
  5. Click the Identity tab. Click This user, and type the name and password for the Workflow System Account.
  6. Add the Workflow System Account to the Privileged Workflow Authors role in the COM+ application package for the workflow event sink.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Registering a Workflow Event Sink

Any authenticated user can create a workflow design as long as he or she is the folder owner and is authorized to register the Collaboration Data Objects (CDO) workflow event sink. You can control who registers the event sink by populating the Can Register Workflow role of the Workflow Event Sink Component Object Model (COM)+ package. The following illustration shows the Component Services dialog box where you populate this role.

Note Before you add users to roles or modify Workflow Event Sink properties, you must shut down the COM+ application if it is running.

Workflow for Microsoft® Exchange 2000 Server supports three events: OnSyncSave, OnSyncDelete, and OnTimer. You enable the workflow folder by registering the event sink for these events in the folder where you want to enforce the workflow process.

Note Be sure to read this FAQ about replicating workflow-enabled folders to Exchange Server 5.5 servers.

You can register the event sink with DEEP scope, which means that all subfolders inherit the same workflow process. Certain rules apply to registering the event sink with DEEP scope. The topic Registering a Workflow Event Sink in a Folder describes these rules in detail.

You can use the event registration item to set the following four properties for the workflow application:

  • http://schemas.microsoft.com/cdo/workflow/defaultprocdefinition identifies the default ProcessDefinition for the folder in which the event fires. You can use either an absolute or a relative URL for this property.
  • http://schemas.microsoft.com/cdo/workflow/adhocflows determines whether or not ad hoc workflows are allowed in the folder where the event fires.
  • http://schemas.microsoft.com/cdo/workflow/enabledebug determines whether or not the workflow engine enables Just-In-Time (JIT) script debugging for the folder that the event fires in.
  • http://schemas.microsoft.com/cdo/workflow/disablesuccessentries determines that the workflow engine does not log success entries to the audit trail.

You never use the OnTimer registration item to set these properties. You must set the defaultprocdefinition and adhocflows fields with the OnSyncSave registration item. The enabledebug Field and disablesuccessentries Field are optional, and you can set them on either the OnSyncSave or the OnSyncDelete registration items or on both. The following table summarizes where to set these fields.

Property | Set with OnSyncSave registration item? | Set with OnSyncDelete registration item? | Set with OnTimer registration item?
http://schemas.microsoft.com/cdo/workflow/ defaultprocdefinition | Yes, mandatory except for ad hoc workflow | No | No
http://schemas.microsoft.com/cdo/workflow/ adhocflows | Yes, mandatory | No | No
http://schemas.microsoft.com/cdo/workflow/ enabledebug | Yes, optional | Yes, optional | No
http://schemas.microsoft.com/cdo/workflow/ disablesuccessentries | Yes, optional | Yes, optional | No

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Privileged Workflow Authors

You enable privileged authors to design powerful workflow applications by making them members of the PrivilegedWorkflowAuthors built-in role. You must grant this permission on each computer running Microsoft® Exchange 2000 Server where people will use the privileged author role.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Example Code

This section does not currently contain any topics. Information will be provided here as it becomes available.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Appendixes

The following topic provides additional information about workflow.

CDO Workflow Objects for Exchange

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


CDO Workflow Objects for Exchange

Collaboration Data Objects (CDO) workflow objects for Microsoft® Exchange 2000 Server provides the tools you need to add workflow to your Web Storage System applications. Driven by the Web Storage System event architecture, CDO workflow for Exchange provides a built-in workflow engine along with custom Component Object Model (COM) components that you can use to create process definitions and action tables that model your application's workflow processes.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Creating Contact Applications

Contacts are collections of information about a person or business, such as phone numbers, e-mail addresses, and pager numbers. You can store contact information in the Web Storage System, Microsoft® Windows® 2000, Microsoft® Active Directory™, or all three.

The topics in this section describe how to create and use Contact applications.

Introduction

Before You Start

Concepts and Architecture

Programming Tasks

Example Code

Related Topics

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Introduction

As business practices become increasingly complex, the ability to reach many people quickly becomes more critical. Contact applications are designed to help you efficiently store and access contact information.

Contact objects are derived from the CDO Person object and are used to store basic information about a person, such as name, address, and phone number. Contact objects are similar to User objects, but are not security principals, so they cannot be used to log onto, or to access resources from, the network.

Contact objects can be created and saved to Microsoft® Active Directory™, the Web Storage System, or both. Contact objects that reside in Active Directory can also be mail-enabled. If you create a mail-enabled contact to represent a consultant, people can e-mail this consultant just as they would another employee, by using an alias.

Some of the benefits of using contacts with Microsoft® Exchange 2000 Server are as follows:

  • The CDO Person COM class object enables faster development by creating and managing contact information stored in the Web Storage System and Active Directory.
  • The CDO Person object enables easy conversion of contact information into the Internet-industry vCard format.
  • A predefined Web Storage System schema.
  • The ability to manipulate contact information through the CDO Person object and Microsoft® Outlook®.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Before You Start

A Contact is represented by the CDO Person object, which is a part of CDO for Exchange 2000 Server (CDOEX). In order to utilize contacts while you are developing your application, you will need to include the Microsoft CDO for Exchange 2000 type library or header file in your project or workspace. The Active DS and the Microsoft ActiveX Data Objects 2.5 type libraries or header files are also commonly used. For more information about configuring your development environment, see Development Environment.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Concepts and Architecture

The topics in this section illustrate key concepts by providing rudimentary examples of using Contacts and the CDO Person object. The examples include conceptual diagrams that help explain the architecture of the technology and the flow of code execution.

Working with the CDO Person Object

Using the IPerson DataSource Property

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Working with the CDO Person Object

The CDO Person object defines methods and properties for managing contact items in the Web Storage System or Microsoft® Active Directory™. Contacts that exist in Active Directory can be saved to the Web Storage System and conversely, from the Web Storage System to Active Directory. CDO handles the underlying information that maps between Active Directory™ Service Interfaces (ADSI) and a schema in the Web Storage System.

The CDO Person Object has the Person COM class that represents a single person who might have a mailbox in the Web Storage System. The IPerson interface contains a comprehensive set of personal and business information properties that can be set and retrieved programmatically.

The IPerson interface contains a Fields property that provides access to a Microsoft Microsoft® ActiveX® Data Objects (ADO) Fields collection of contact-related schema fields. These fields provide additional settings, such as BusinessHomePage, that are not CDO properties.

For compatibility with other contact and personal information managers (PIM) programs, the IPerson interface contains the GetvCardStream method for saving contact information to a file in a vCard-compliant Multipurpose Internet Mail Extensions (MIME) format.

The DataSource property provides access to the IDataSource interface on contact items for saving and opening contact items to and from the Web Storage System or ADO. Script users can use the GetInterface method to access the IDataSource interface.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Using the IPerson DataSource Property

The CDO IPerson interface defines the DataSource property, which provides access to the IDataSource interface connected to the contact. The IDataSource interface can then be used to save and open contacts to and from the Web Storage System and Microsoft® Active Directory™.

The DataSource property can be accessed directly in order to save or open contacts, as in the following code snippet, where iPer is a Person object:

iPer.DataSource.SaveTo strURL

The DataSource property can also be used to return the IDataSource interface on the Contact object. The returned IDataSource interface can be used to save or open contacts, as in the following code snippet, where iPer is a Person object and iDS is an IDataSource interface:

set iDS = iPer.DataSource
iDS.SaveTo strURL

Script users can take advantage of the IPerson. GetInterface method to access the IDataSource interface, as in the following code snippet, where iPer is a Person object and iDS is an IDataSource interface:

set iDS = iPer.GetInterface("IDataSource")

Related Topics

  • IPerson Interface
  • IDataSource Interface

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Programming Tasks

This section contains topics consisting of instructional tasks and sample code for Contact applications. Each task is explained at length, providing intstructional text describing the "hows" and "whys" of programing the task.

Creating Contacts

Saving Contacts to Active Directory

Opening Contacts from Active Directory

Saving Contacts to the Web Storage System

Opening Contacts from the Web Storage System

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Creating Contacts

Creating a contact using the CDO Person object involves setting informational properties and saving the contact to either the Web Storage System or Microsoft® Active Directory™.

The following sections describe how to create contacts:

Creating a Contact in the Web Storage System

Creating a Contact in Active Directory

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Creating a Contact in the Web Storage System

Creating a contact involves setting informational properties and saving the contact to the Web Storage System.

Example

The following example creates a contact using the CDO Person object and saves it to the Web Storage System.

Visual Basic

Note This example uses a file URL with the Exchange OLE DB (ExOLEDB) provider. The ExOLEDB provider also supports the HTTP URL scheme. Using the HTTP URL scheme allows both client and server applications to use a single URL scheme.
Sub CreateContactWebStore()

Dim oPerson As New CDO.Person
Dim strURL As String

oPerson.FirstName = "John"
oPerson.LastName = "Smith"
oPerson.HomeCity = "Redmond"
oPerson.HomeState = "Washington"
oPerson.Email = "jsmith@somewhere.microsoft.com"
oPerson.Fields("objectClass").Value = "contact"
oPerson.Fields.Update

'URL to save the contact using Exchange OLE DB Provider
strURL = "file://./backofficestorage/fullyqualifieddomain.Microsoft.Com/MBX/User1/Contacts/JohnSmith.eml"

'Save the contact to Web Storage System
oPerson.DataSource.SaveTo strURL

End Sub

By default, the CDO person object creates a user. In the preceding code, the oPerson.Fields("objectClass").Value is set to type "contact" in order to create a contact.

The objectClass value is an array of variants, however the property can accept a single value. The value might be one of the following:

  oPerson.Fields("objectClass").Value = "contact"
  oPerson.Fields("objectClass").Value = Array("top", "person", _ "organizationalPerson", "contact")

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Creating a Contact in Active Directory

Creating a contact involves setting informational properties and saving the contact to Microsoft® Active Directory™.

The LDAP URL consists of prefixes and distinguishing names for the contact that address its placement in Active Directory's hierarchy. Use the prefix CN for common names, DC for domains, and O or OU for organizations to refer to the object.

CN is used to uniquely identify the object’s common name, as well as to indicate its classification, such as users.

Use as many DCs as necessary for each qualification in the domain name, including a DC for sub-domains.

Example LDAP URL for a Person Object

If James Smith is a person with a Microsoft® Exchange mailbox in the domain named somewhere.microsoft.com, and the name of the Exchange 2000 Server is the server, then the LDAP URL would be:

LDAP://theserver/cn=jamessmith,cn=users,dc=somewhere,dc=microsoft,dc=com

Example

The following example creates a contact using the CDO Person object and saves it to Active Directory.

Visual Basic

Dim oPerson As New CDO.Person
Dim strURL As String

oPerson.FirstName = "John"
oPerson.LastName = "Smith"
oPerson.HomeCity = "Redmond"
oPerson.HomeState = "Washington"
oPerson.Email = "jsmith@somewhere.microsoft.com"
oPerson.Fields("objectClass").Value = "contact"
oPerson.Fields.Update

strURL = "LDAP://theserver/cn=johnsmith,cn=users,dc=somewhere,dc=microsoft,dc=com"

'Save the contact
oPerson.DataSource.SaveTo strURL

By default, the CDO person creates a user. In the preceding code, the oPerson.Fields("objectClass").Value is set to type "contact" in order to create a contact.

The objectClass value is an array of variants, however the property can accept a single value. Thus, the value might be one of the following:

  oPerson.Fields("objectClass").Value = "contact"
  oPerson.Fields("objectClass").Value = Array("top", "person", "organizationalPerson", "contact")

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Opening Contacts from Active Directory

The Iperson.DataSource property returns the attached IDataSource interface. The IDataSource interface exposes two methods that may be used for opening contacts from the Microsoft® Active Directory™: Open, and OpenObject.

The IDataSource.Open method may be called to bind to and open data from the item at the specified URL. The IDataSource.OpenObject is intended to allow you to easily open data from another object at run time, rather than from a particular store or database.

The LDAP binding string consists of prefixes and distinguishing names that address the contact's placement in Active Directory's hierarchy. To refer to the object, use the prefix CN for common names, DC for domains, and O or OU for organizations. CN is used to uniquely identify the object's common name, as well as to indicate its classification, such as users. Use as many DCs as necessary for each qualification in the domain name, including a DC for sub-domains.

Example

The following example shows how to open a contact from the Active Directory. The LDAP binding string is build with the person's first and last names, user's designation, and the domain of the server. The IDataSource.Open method then uses the LDAP binding string to bind to, and open, the contact from the Active Directory.

Visual Basic

'Declare variables
Dim iPer As New CDO.Person
Dim strLDAP As String

'Setup the LDAP string
strLDAP = "LDAP://servername/cn=Derek Wildstar, cn=users, dc=domain, dc=com"

'Open the contact to Active Directory
iPer.DataSource.Open strURL

Related Topics

  • IDataSource Interface

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Saving Contacts to Active Directory

The Iperson.DataSource property returns the attached IDataSource interface. The IDataSource interface exposes four methods that may be used for saving contacts to the Microsoft® Active Directory™: Save, SaveTo, SaveToContainer, and SaveToObject.

After binding the contact to a data source, the IDataSource.Save method may be called to commit changes back to the bound data source. The IDataSource.SaveTo method may be called to bind to, and save data into, the item at the specified URL. In order to bind and save data into a new item at a specified URL, the IDataSource.SaveToContainer method can be called. The IDataSource.SaveToObject is intended to allow you to easily save data into another object at run time.

The LDAP binding string consists of prefixes and distinguishing names for the contact that address its placement in Active Directory's hierarchy. Use the prefix CN for common names, DC for domains, and O or OU for organizations to refer to the object. CN is used to uniquely identify the object's common name, as well as to indicate its classification, such as users. Use as many DCs as necessary for each qualification in the domain name, including a DC for sub-domains.

Example

The following example shows how to create a contact and save it to the Active Directory. The LDAP binding string is built with the person's first and last names, user's designation, and the domain of the server. The IDataSource.SaveTo method then uses the LDAP binding string to save the contact to the Active Directory.

Visual Basic

'Declare variables
Dim iPer As New CDO.Person
Dim strLDAP As String

With iPer
    'Set first and last names and company name
    .FirstName = "Derek"
    .LastName = "Wildstar"
    .Company = "Starblazers, Inc."
    'Indicate that this is a contact
    .Fields("objectClass").Value = "contact"
    'Save changes made to propeties
    .Fields.Update
End With

'Setup the LDAP string
strLDAP = "LDAP://servername/cn=Derek Wildstar, cn=users, dc=domain, dc=com"

'Save the contact to Active Directory
iPer.DataSource.SaveTo strURL

Related Topics

  • IDataSource Interface

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Opening Contacts from the Web Storage System

The Iperson.DataSource property returns the attached IDataSource interface. The IDataSource interface exposes two methods that may be used for opening contacts from the Web Storage System: Open, and OpenObject.

The IDataSource.Open method may be called to bind to and open data from the item at the specified URL. The IDataSource.OpenObject is intended to allow you to open data easily from another object at run time, rather than from a particular store or database.

Example

The following example shows how to open a contact from a user's contact folder within their mail account.

Visual Basic

'Declare variables
Dim iPer Ss New CDO.Person
Dim strURL As String

'Setup the URL for the contact in the mail users contact folder
strURL = "http://server.domain.com/exchange/UserAlias/Contacts/JohnSmith.eml"

'Open the contact
iPer.DataSource.Open strURL

Related Topics

  • IDataSource Interface

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Saving Contacts to the Web Storage System

The Iperson.DataSource returns the attached IDataSource interface. The IDataSource interface exposes four methods that may be used for saving contacts to the Web Storage System: Save, SaveTo, SaveToContainer, and SaveToObject.

After binding the contact to a data source, the IDataSource.Save method may be called to commit changes back to the bound data source. The IDataSource.SaveTo method may be called to bind to, and save data into, the item at the specified URL. In order to bind and save data into a new item at a specified URL, the IDataSource.SaveToContainer method can be called. The IDataSource.SaveToObject is intended to allow you to easily save data into another object at run time.

Example

The following example shows how to create a contact and save it to a mail users contact folder within the Web Storage System.

Visual Basic

'Declare variables
Dim iPer As New CDO.Person
Dim strURL As String

With iPer
    'Set first and last names and company name
    .FirstName = "Derek"
    .LastName = "Wildstar"
    .Company = "Starblazers, Inc."
    'Indicate that this is a contact
    .Fields("objectClass").Value = "contact"
    'Save changes made to propeties
    .Fields.Update
End With

'Setup the URL for the users contact folder
strURL = "http://server.domain.com/exchange/UserAlias/Contacts"

'Save the contact to the users contact folder
iPer.DataSource.SaveTo strURL

Related Topics

  • IDataSource Interface

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Example Code

The topics in this section provide examples in Microsoft® Visual Basic® and Microsoft® Visual C++® on how to create, modify, delete, list, search for, and use Contacts.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Creating a Contact

The following examples create a mail-enabled contact. The respective CDO and Active Directory™ Service Interfaces (ADSI) objects expose the IMailRecipient Interface. Note that these examples use the LDAP protocol to access the Microsoft® Active Directory™ directory service in Microsoft® Windows® 2000. Any information that needs to be updated in Microsoft® Exchange 2000 Server is updated behind the scenes as part of CDO for Exchange Management (CDOEXM) management.

Example (CDO)

The following Microsoft® Visual Basic® example uses the CreateUserURL function, which is described in the topic Creating a User URL.

Visual Basic

'//////////////////////////////////////////////////////////////////////////////////
'// Function:   CreateNewCDOUserOrContact
'// Purpose:    To create a user in a given Container in the DS via CDO.
'// Input/Output:
'//     strUserName  = contains name of user to be created;
'//                        If not provided CreateUserURL() will create a name such as DSIPerson_12345600
'//     strUserOrContact = contains the type: "User" or "Contact"
'//     strContainerName [Optional] = contains name of container to create user in.
'//                        If nothing passed in then user created at domain level.
'// Notes:
'//  Caller needs to verify user is unique before calling this function
'//
'//////////////////////////////////////////////////////////////////////////////////

Public Function CreateNewCDOUserOrContact(ByVal strUserName As String, _
                                          ByVal strUserOrContact As String, _
                                          Optional ByVal strContainerName As String) As Boolean

    On Error Resume Next
    Dim oPerson     As New CDO.Person
    Dim strURL      As String
    Dim Result   As Boolean

    Result = True

    Result = Result And CreateUserURL(strURL, strContainerName, False, strUserName)

    oPerson.FirstName = strUserName
    Result = Result And CheckError("Set FirstName prop of Person to " & strUserName)
    If StrComp(LCase(strUserOrContact), "contact", vbTextCompare) = 0 Then
        oPerson.Fields("objectClass") = "contact"
        oPerson.Fields.Update
        oPerson.Fields.Resync
    End If

    oPerson.DataSource.SaveTo strURL
    Result = Result And CheckError("SaveTo " & strURL)

    'CleanUp
    Set oPerson = Nothing
    CreateNewCDOUserOrContact = Result
End Function

VBScript

Function CreateContact_CDO( _
                            serverName, _
                            domainName, _
                            emailAddr, _
                            firstName, _
                            lastName )

 ' serverName  - Server used to create contact. Example: "MyServer6"
 ' domainName  - Domain for contact.            Example: "mydomain3.microsoft.com"
 ' emailAddr   - Contact's SMTP e-mail address.  Example: "jsmith@mydomain4.microsoft.com"
 ' firstName   - Contact's first name,          Example: "James"
 ' lastName    - Contact's last name.           Example: "Smith"

 Dim iPerson  ' IPerson Interface
 Dim iRecip   ' IMailRecipient Interface
 Dim domainDN ' Distinguised name for Domain
 Dim recipN   ' Recipient e-mail name. Used to construct DN for contact.

 ' Construct the DN for the domain
 Dim domTokens
 domTokens     = split(domainName,".",-1,1)
 domainDN      = join(domTokens,",dc=")
 domainDN      = "dc=" & domainDN

 'Get recipient name to construct DN for contact
 recipN = Mid(emailAddr,1,InStr(1,emailAddr,"@",1) - 1)

 Set iPerson = CreateObject("CDO.Person")

 ' Now create the object in Active Directory
 With iPerson
   .FirstName = firstName
   .LastName  = lastName
   .Fields("objectClass") = "contact"
   .Fields.Update
   .DataSource.SaveTo "LDAP://" + serverName + "/CN=" + recipN + _
                       ",CN=Users," + domainDN

   Set iRecip = .GetInterface("IMailRecipient")
   iRecip.MailEnable "smtp:" & emailAddr
   .DataSource.Save
 End With

 Set CreateContact_CDO = iPerson

End Function

Example (ADSI)

Visual Basic

Sub CreateADSI_Contact(MDBName As String, _
                       DomainName As String, _
                       recipname As String, _
                       ForwardingDomain As String, _
                       FirstName As String, _
                       LastName As String)

'MDBName is something like "MyMDB6"
'DomainName is something like "DC=MYDOMAIN3,DC=microsoft,DC=com"
'recipname is is the e-mail alias eg. "jamessmith"
'ForwardingDomain is a domain like "somewhere.microsoft.com"

Dim objContact As IADs
Dim objContainer As IADsContainer
Dim objRecip As CDOEXM.MailRecipient
Dim recip As String

'recipname is contact name (eg. jamessmith)
'ForwardingAddress is full forwarding address,
'such as jamessmith@somewhere_else.microsoft.com
recip = "CN=" & recipname

' get the container
Set objContainer = GetObject("LDAP://CN=" + MCBName + "/" + _
                            "CN=users," + DomainName)

' create a Contact
Set objContact = objContainer.Create("contact", recip)
objContact.Put "sn", recipname
objContact.Put "givenName", recipname
objContact.SetInfo

Set objRecip = objContact
Dim FwdAddress As String
FwdAddress = "smtp:" + recipname + "@" + ForwardingDomain
objRecip.MailEnable FwdAddress
objContact.SetInfo

End Sub

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Searching for Contacts

When using the CDO Person object, you can search contacts for specific properties and fields. For example, a recruiter may want to search a contact list for candidates who live in California.

Example

The following example uses the CDO Person object to search for candidates who live in California.

Visual Basic

'////////////////////////////////////////////////////////////////////////////////////////////////////
'//Function: SearchContacts
'//Purpose:	Searches through the contacts folder of a specified mail-directory for candidates who
'//			live in California.
'//Input/Output:
'//	strWhereClause = Contains the Where clause of the SQL search string.
'//	iMbx = the Mailbox which contains the contacts folder to be searched.
'//	Conn = the active ADODB Connection object for the contacts folder to be searched.
'//Notes:
'////////////////////////////////////////////////////////////////////////////////////////////////////
Function SearchContacts( strWhereClause as String, iMbx as CDO.IMailbox, Conn as ADODB.Connection )

  Dim Rs as New ADODB.Recordset
  Set Rs.ActiveConnection = Conn

  strSQL = "select ""DAV:href"", " & _
                   """urn:schemas:contacts:fileas"", " & _
                   """urn:schemas:contacts:email1""" & _
                   "from "

  strSQL = strSQL & """" & iMbx.Contacts & """ "
  strSQL = strSQL & strWhereClause

  Rs.Open strSQL, Conn

End Function

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Getting a Contact's vCard Stream

Microsoft® Exchange 2000 Server supports the Internet-industry vCard standard for obtaining contact information through the CDO Person object. You can import contact information from any vCard-compliant contact application.

The GetVCardStream Method on the IPerson Interface returns contact information by returning a Microsoft® Microsoft® ActiveX® Data Objects (ADO) stream object.

Example

The following example uses the CDO Person object to obtain a contact’s vCard information.

Visual Basic

Dim oPerson As New CDO.Person
Dim strm As New ADODB.Stream

'Assume strURL is a valid URL to a person contact item
oPerson.DataSource.Open strURL

'you can set the ADO Stream object to the returned vCard stream
Set strm = oPerson.GetvCardStream

'Save the stream to a file
strm.SaveToFile "d:\vcard.txt", adSaveCreateOverwrite

'You don't have to set a Stream object,
'just use the Stream methods off GetvCardStream directly
oPerson.GetvCardStream.SaveToFile "d:\vcard.txt", adSaveCreateOverwrite

Related Topics

  • Creating a Contact from a vCard Stream

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Creating a Contact from a vCard Stream

Example

The following example creates a contact by loading saved vCard information into a CDO Person object.

Visual Basic

Dim objStream As Stream
Dim objPerson As New CDO.Person

'Set the ADO stream object to the Person object's vCard stream
Set objStream = objPerson.GetvCardStream

'Load the contents of a file containing the vCard information into the stream
objStream.LoadFromFile "C:\vcard.txt"

'Send the buffered data to the Person object's vCard stream
objStream.Flush

Related Topics

  • Getting a Contact's vCard Stream

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Listing Contacts Using ADO

VBScript

Note The following example uses a file URL with the Exchange OLE DB (ExOLEDB) provider. The ExOLEDB provider also supports the HTTP URL scheme. Using the HTTP URL scheme allows both client and server applications to use a single URL scheme.
'Listing Contacts using ADO
-->

<!--
'
'Steps to test this sample.
'
'1) Create a folder named "test" under inetpub/wwwroot.
'2) Save the above file in that folder with the mentioned name.
'3)  Make the changes to the above file i.e. Change the strLocalPath  and DomainName variables to reflect your mailbox and domain.
'4) Save the file.
'5) open internet service manager and browse to the "test"  folder
'6) right click and go to properties
'7) go to the "Directory Security" tab.
'8) Click on "Edit" button next to the "handshake" icon
'9) Uncheck "Anonymous Access"
'10) check the "Digest Authentication" and "Integrated windows authentication" boxes
'11) click ok
'12) click ok
'13) Load the asp in the browser.
-->

<%@ Language=VBScript %>
<html><body>

<%

Dim Rs
Dim Rec
Dim strURL

'specify your own domain
DomainName = "nrnobledom2.extest.microsoft.com"
'specify a URL to folder or item
strLocalPath = "MBX/User1/Contacts"

Set Rec = CreateObject("ADODB.Record")
Set Rs = CreateObject("ADODB.Recordset")
strURL = "file://./backofficestorage/" & DomainName & "/" & strLocalPath

Rec.Open strURL

Set Rs.ActiveConnection = Rec.ActiveConnection

Rs.Source = "SELECT ""DAV:href"", " & _
" ""urn:schemas:contacts:email1"", " & _
" ""urn:schemas:contacts:nickname"", " & _
" ""urn:schemas:contacts:title"" " & _
"FROM scope('shallow traversal of """ & strURL & """') "
Rs.Open

%> <FONT FACE=ARIAL SIZE=2>
<br><br>
<TABLE cellspacing=0 cellpadding=4>
<%

Do Until Rs.EOF
response.write "<tr><td>"

Response.Write "Nickname : " & Rs.Fields("urn:schemas:contacts:nickname").Value
response.write "</td><td>"

Response.Write "Email1 : " & Rs.Fields("urn:schemas:contacts:email1").Value
response.write "</td><td>"

Response.Write "Title : " &Rs.Fields("urn:schemas:contacts:title").Value
response.write "</td><td>"

Rs.MoveNext
Loop

%>
</table>

</body></html>
<!--

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Changing an Existing Contact with CDOEX

Visual Basic

Note The following example uses a file URL with the Exchange OLE DB (ExOLEDB) provider. The ExOLEDB provider also supports the HTTP URL scheme. Using the HTTP URL scheme allows both client and server applications to use a single URL scheme.
'Changing an exisitng Contact with ADO and CDOEx
'
'Reference the project with
' - Active Directory Type Library
' - Microsoft CDO For Exchange 2000 Library
' - Microsoft ActiveX Data Objects 2.5 Library

Private Sub ChangeContact()

Dim oRec As ADODB.Record
Dim sURL As String
Dim sSQL As String
Dim oRst As ADODB.Recordset
Dim sHREF As String
Dim sDomainName As String
Dim sLocalPath As String
Dim sMailBox As String
Dim sChangeName As String
Dim bFound As Boolean
Dim oAdSysInfo As ActiveDs.ADSystemInfo
Set oAdSysInfo = CreateObject("ADsystemInfo")
sDomainName = oAdSysInfo.DomainDNSName

sMailBox = "user1"
'specify a URL to the contacts folder or an contact item
sLocalPath = "MBX/" & sMailBox & "/contacts"
'sLocalPath = "MBX\administrator\contacts"
sChangeName = "user2"
Set oRec = CreateObject("ADODB.Record")
Set oRst = CreateObject("ADODB.Recordset")

sURL = "file://./backofficestorage/" & sDomainName & "/" & sLocalPath
oRec.Open sURL

'create the SQL query for the recordset
sSQL = "select "
sSQL = sSQL & " ""urn:schemas:mailheader:content-class"""
sSQL = sSQL & ", ""DAV:href"""
sSQL = sSQL & ", ""DAV:displayname"""
sSQL = sSQL & " from scope ('shallow traversal of " & Chr(34)
sSQL = sSQL & sURL & """') "
sSQL = sSQL & " WHERE ""DAV:ishidden"" = false"

'open the recordset, a list of folder and/or items
oRst.Open sSQL, oRec.ActiveConnection
bFound = False
Do While Not oRst.EOF
    Dim oPer As New CDO.Person
    Dim sRecordSource As String
    Dim sNameToChange As String
    sRecordSource = oRst.Fields("DAV:href")
    oPer.DataSource.Open sRecordSource, , adModeReadWrite
    sNameToChange = oPer.FirstName
    sNameToChange = sNameToChange & IIf((oPer.MiddleName = ""), " ", " " & oPer.MiddleName & " ")
    sNameToChange = sNameToChange & oPer.LastName
    If Trim(UCase(sNameToChange)) = UCase(sChangeName) Then
        bFound = True
Exit Do
End If
oRst.MoveNext
Set oPer = Nothing
Loop
If Not bFound Then
MsgBox sChangeName & ": No Such Contact to Change Please Check the Name again"
Else
'The contact was found you can change the contact attributes on the person object itself
oPer.Company = "Microsoft"
oPer.email = "someone@microsoft.com"
oPer.WorkStreet = "One Microsoft Way"
oPer.WorkCity = "Redmond"
oPer.WorkCountry = "USA"
oPer.WorkPostalCode = "98052"

'Some additional properties are listed on the Web Storage System schema which can be accessed using the fields collection as shown below

oPer.Fields("urn:schemas:contacts:billinginformation") = "Sample Billing Information" 'Named Constant for Billing information is not available
oPer.Fields("urn:schemas:contacts:businesshomepage") = "http://www.microsoft.com"
oPer.Fields("urn:schemas:contacts:spousecn") = "Spouse Name" 'Spouse Common Name
oPer.Fields.Update 'Update the fields collection
oPer.DataSource.Save
End If
Set oPer = Nothing
End Sub

Sub Main()

 Call ChangeContact

End Sub

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Adding Contact Information into Messages with CDOEX

Visual Basic

'Adding Contact Info into messages with CDOEx

Private Sub Main()

   Dim strServerName As String
   Dim strDomainName As String
   Dim strRecipName As String
   Dim strURL As String
   Dim objContact As New CDO.Person

    'create LDAP query string to find right contact "record"

   strServerName = "Server6"
   strDomainName = "DC=MYDOMAIN3,DC=microsoft,DC=com"
   strRecipName = "User1"  'alias

    'Get Contact from server
   objContact.DataSource.Open strURL

    If Err.Number = 0 Then
      'no errors, continue  and create new message
      Set objMessage = New CDO.Message
      With objMessage   ' "With" statement reduces object reference overhead
         .Subject = "test message to contact"
         .TextBody = "This is a simple text message to a contact"
         .From = " <sender alias>"
         .To = objContact.Email   'email address of found contact
         .Configuration.Fields("cdoSendUsing") = cdoSendUsingExchange  'use exch server
         .Configuration.Fields.Update
         .Send
      End With
   End If

    'explicitly release objects
   Set objContact = Nothing
   Set objMessage = Nothing

 End Sub

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Deleting an Existing Contact with CDOEX

Visual Basic

Note The following example uses a file URL with the Exchange OLE DB (ExOLEDB) provider. The ExOLEDB provider also supports the HTTP URL scheme. Using the HTTP URL scheme allows both client and server applications to use a single URL scheme.
' Deleting an existing contact with CDOEx

Sub DeleteContact(sDeleteName As String, sMailbox As String)

Dim oRec As ADODB.Record
Dim sURL As String
Dim sSQL As String
Dim oRst As ADODB.Recordset
Dim sHREF As String
Dim sDomainName As String
Dim sLocalPath As String
Dim sMailbox As String
Dim sDeleteName As String
Dim bFound As Boolean
Dim oAdSysInfo As ActiveDs.ADSystemInfo

Set oAdSysInfo = CreateObject("ADsystemInfo")
sDomainName = oAdSysInfo.DomainDNSName

'specify a URL to the contacts folder or an contact item
sLocalPath = "MBX\" & sMailbox & "\contacts"

Set oRec = CreateObject("ADODB.Record")
Set oRst = CreateObject("ADODB.Recordset")

sURL = "file://./backofficestorage/" & sDomainName & "/" & sLocalPath
oRec.Open sURL

'create the SQL query for the recordset
sSQL = "select "
sSQL = sSQL & " ""urn:schemas:mailheader:content-class"""
sSQL = sSQL & ", ""DAV:href"""
sSQL = sSQL & ", ""DAV:displayname"""
sSQL = sSQL & " from scope ('shallow traversal of " & Chr(34)
sSQL = sSQL & sURL & """') "
sSQL = sSQL & " WHERE ""DAV:ishidden"" = false"

'open the recordset, a list of folder and/or items
oRst.Open sSQL, oRec.ActiveConnection
bFound = False
Do While Not oRst.EOF
    Dim oPer As New cdo.Person
    Dim sRecordSource As String
    Dim sNameToDelete As String
    sRecordSource = oRst.Fields("DAV:href")
    oPer.DataSource.Open sRecordSource, , adModeReadWrite
    sNameToDelete = oPer.FirstName
    sNameToDelete = sNameToDelete & IIf((oPer.MiddleName = ""), " ", " " & oPer.MiddleName & " ")
    sNameToDelete = sNameToDelete & oPer.LastName
    If Trim(UCase(sNameToDelete)) = UCase(sDeleteName) Then
        bFound = True
        oRst.Delete
        Exit Do
    End If
    oRst.MoveNext
    Set oPer = Nothing
Loop
If Not bFound Then
    Debug.Print sDeleteName & ": No Such Contact to Delete Please Check the Name again"
End If
End Sub

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Adding a New Contact with CDOEX

Visual C++

Note The following example uses a file URL with the Exchange OLE DB (ExOLEDB) provider. The ExOLEDB provider also supports the HTTP URL scheme. Using the HTTP URL scheme allows both client and server applications to use a single URL scheme.
//Adding a new Contact with CDOEx

#import <cdoex.dll> rename_namespace("CDO") raw_interfaces_only

#include <stdio.h>
#include <tchar.h>

enum ConnectModeEnum
{
    adModeUnknown = 0,
    adModeRead = 1,
    adModeWrite = 2,
    adModeReadWrite = 3,
    adModeShareDenyRead = 4,
    adModeShareDenyWrite = 8,
    adModeShareExclusive = 12,
    adModeShareDenyNone = 16,
    adModeRecursive = 4194304
};

enum RecordCreateOptionsEnum
{
    adCreateCollection = 8192,
    adCreateStructDoc = -2147483648,
    adCreateNonCollection = 0,
    adOpenIfExists = 33554432,
    adCreateOverwrite = 67108864,
    adFailIfNotExists = -1
};

enum RecordOpenOptionsEnum
{
    adOpenRecordUnspecified = -1,
    adOpenSource = 8388608,
    adOpenAsync = 4096,
    adDelayFetchStream = 16384,
    adDelayFetchFields = 32768
};

void dump_com_error(_com_error &e)
{
    _tprintf(_T("Oops - hit an error!\n"));
    _tprintf(_T("\a\tCode = %08lx\n"), e.Error());
    _tprintf(_T("\a\tCode meaning = %s\n"), e.ErrorMessage());
    _bstr_t bstrSource(e.Source());
    _bstr_t bstrDescription(e.Description());
    _tprintf(_T("\a\tSource = %s\n"), (LPCTSTR) bstrSource);
    _tprintf(_T("\a\tDescription = %s\n"), (LPCTSTR) bstrDescription);
}

struct StartOle {
    StartOle() { CoInitialize(NULL); }
    ~StartOle() { CoUninitialize(); }
} _inst_StartOle;

void main(int argc, char** argv)
{
   HRESULT hr = S_OK;

   if(argc != 2)
   {
         printf("Usage: CreateContact\r\n");
         printf("Example: CreateContact \"file://./backofficestorage/MangoDomain.extest.microsoft.com/MBX/User1/Contacts\"\n");
         exit(0);
   }

   wchar_t* folderURL = NULL;
   size_t size;
   size = mbstowcs(NULL,argv[1],0);
   folderURL = (wchar_t*)malloc(size * sizeof(wchar_t*) + 1);
   mbstowcs(folderURL,argv[1],size+1);

   BSTR bstrFolderURL = SysAllocString(folderURL);

   try
   {
      CDO::IPersonPtr pPerson(_uuidof(CDO::Person));
      CDO::IDataSourcePtr pDsrc;

      pPerson->put_FirstName(L"John");
      pPerson->put_LastName(L"Smith");
      pPerson->put_HomeCity(L"Bellevue");
      pPerson->put_HomeState(L"Washington");
      pPerson->put_Email(L"JohnSmith@somewhere.com");
      pPerson->get_DataSource(&pDsrc);

      hr = pDsrc->SaveToContainer(bstrFolderURL,
                           0,
                           (enum CDO::ConnectModeEnum) adModeReadWrite,
                           (enum CDO::RecordCreateOptionsEnum)adCreateOverwrite,
                           (enum CDO::RecordOpenOptionsEnum)adOpenSource,
                           L"",
                           L"");

      if (SUCCEEDED(hr))
         _tprintf(_T("Contact created\n"));

   }
   catch(_com_error &e)
   {
      dump_com_error(e);
   }

   SysFreeString(bstrFolderURL);
}

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Deleting an Existing Contact with CDOEX

Visual C++

Note The following example uses a file URL with the Exchange OLE DB (ExOLEDB) provider. The ExOLEDB provider also supports the HTTP URL scheme. Using the HTTP URL scheme allows both client and server applications to use a single URL scheme.
//Deleting an existing Contact with CDO
//Need to link to these libraries: activeds.lib adsiid.lib

#include <activeds.h>
#include <stdio.h>
#include <shlwapi.h>

#import <msado15.dll> no_namespace rename("EOF", "adoEOF")

#import <cdoex.dll> no_namespace

HRESULT GetDomainName(BSTR * bstrDomainName);
HRESULT DeleteContacts(BSTR bstrDomainName, LPSTR lpUser, LPSTR lpContactName);

struct StartOle {
    StartOle() { CoInitialize(NULL); }
    ~StartOle() { CoUninitialize(); }
} _inst_StartOle;

void main()
{
   HRESULT      hr = S_OK;
   BSTR      bstrDomainDNSName;

   // Get Domain Name
   hr = GetDomainName(&bstrDomainDNSName);
   printf("Domain DNS Name: %S\n", bstrDomainDNSName);

   // TODO: change Username and Contact full name
   // Delete Contact "John Smith" in "User1" mailbox
   hr = DeleteContacts(bstrDomainDNSName, "User1", "john smith");
}

//////////////////////////////////////////////////////////////////////////////////////////////////
// DeleteContacts
//
// Params:
//         [in] LPSTR lpUser            Username
//         [in] LPSTR lpContactName      Full Name of a contact to be deleted
// Output:   HRESULT
// Purpose:   Delete a contact based on the full name.
/////////////////////////////////////////////////////////////////////////////////////////////////
HRESULT DeleteContacts(BSTR bstrDomainName, LPSTR lpUser, LPSTR lpContactName)
{
   HRESULT hr = S_OK;
   int iRecCount = 0;

   _bstr_t szConnString = "file://./backofficestorage/" +                       (_bstr_t)bstrDomainName +                      "/MBX/" +                       (_bstr_t)lpUser +                      "/Contacts";

   char ContactFullName[100];

   try {
      _ConnectionPtr   pConn(_uuidof(Connection));
      _RecordsetPtr   pMyContacts(_uuidof(Recordset));
      IPersonPtr      pPerson(_uuidof(Person));
      IDataSourcePtr   pDsrc;

      pConn->Provider = "Exoledb.DataSource";

      hr = pConn->Open(szConnString, "", "", 0);
      if (FAILED(hr))
      {
         printf("Open Connection Failed\n");
         return hr;
      }

      if (pConn->State == adStateOpen)
         printf("Connection Opened\n");
      else
      {
         printf("Connection Failed\n");
         return hr;
      }

      _bstr_t strSQL = "Select \"DAV:displayname\",       \"DAV:href\"       from scope       ('shallow traversal of \""+       szConnString +       "\"')";

      hr = pMyContacts->Open(strSQL,
                     pConn->ConnectionString,
                     adOpenForwardOnly,
                     adLockOptimistic,
                     0);
      if (FAILED(hr))
      {
         printf("Open Contacts Failed\n");
         return hr;
      }

      printf("Open Contacts: \n");

      iRecCount = pMyContacts->RecordCount;

      if (iRecCount == 0)
      {
         printf("No Contacts Found\n\n");
         if (SUCCEEDED(hr = pMyContacts->Close()))
            printf("Close Contacts\n");
         if (SUCCEEDED(hr = pConn->Close()))
            printf("Close Connection\n");
         return hr;
      }

      hr = pMyContacts->MoveFirst();
      if (FAILED(hr))
      {
            printf("MoveFirst Failed\n");
            return hr;
      }

      for (int i = 0; i < iRecCount; i++)
      {
         FieldsPtr pFlds = pMyContacts->GetFields();
         FieldPtr pFld = pFlds->GetItem("DAV:href");

         hr = pPerson->get_DataSource(&pDsrc);

         hr = pDsrc->Open((_bstr_t)pFld->Value,
                  NULL,
                  adModeReadWrite,
                  adFailIfNotExists,
                  adOpenSource,
                  "",
                  "");

         sprintf(ContactFullName, "%s %s", (char *)pPerson->FirstName, (char *)pPerson->LastName);

         // StrCmpI is not cse-sensitive
         if (!StrCmpI(ContactFullName, lpContactName))
         {
            hr = pMyContacts->Delete(adAffectCurrent);
            if (SUCCEEDED(hr))
               printf("Delete Contact: %s\n", lpContactName);
            else
               printf("Delete Contact: %s Failed\n", lpContactName);
         }

         printf("\n");
         hr = pMyContacts->MoveNext();
         if (FAILED(hr))
         {
            printf("MoveNext Failed\n");
            return hr;
         }

         pFlds = NULL;
         pFld = NULL;
      }

      hr = pMyContacts->Close();
      if (FAILED(hr))
      {
         printf("Close Contacts Failed\n");
         return hr;
      }
      else
         printf("Close Contacts\n");

      hr = pConn->Close();
      if (FAILED(hr))
      {
         printf("Close Connection Failed\n");
         return hr;
      }
      else
         printf("Connection Closed\n\n");

      return hr;

   }
   catch(_com_error e)
   {
      printf("HResult = %x\n", e.Error());
      printf("%S\n", e.Description());
      return hr;
   }
}

//////////////////////////////////////////////////////////////////////////////////////////////////
// GetDomainName
//
// Params:   [out] BSTR * bstrDomainName
// Output:   HRESULT
// Purpose: Retrieve the Domain DNS name.
/////////////////////////////////////////////////////////////////////////////////////////////////
HRESULT GetDomainName(BSTR * bstrDomainName)
{
   HRESULT hr = S_OK;
   IADsADSystemInfo *pADsys;

   hr = CoCreateInstance(CLSID_ADSystemInfo,
                    NULL,
                    CLSCTX_INPROC_SERVER,
                    IID_IADsADSystemInfo,
                    (void**)&pADsys);

   hr = pADsys->get_DomainDNSName(bstrDomainName);

   if (pADsys)
      pADsys->Release();
   return  hr;
}

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Changing an Existing Contact with CDOEX

Visual C++

Note The following example uses a file URL with the Exchange OLE DB (ExOLEDB) provider. The ExOLEDB provider also supports the HTTP URL scheme. Using the HTTP URL scheme allows both client and server applications to use a single URL scheme.
//Changing an existing Contact with CDO
//Need to link to activeds.lib adsiid.lib

#include <activeds.h>
#include <stdio.h>
#include <shlwapi.h>

#import <msado15.dll> no_namespace rename("EOF", "adoEOF")

#import <cdoex.dll> no_namespace

HRESULT GetDomainName(BSTR * bstrDomainName);
HRESULT ChangeContacts(BSTR bstrDomainName, LPSTR lpUser, LPSTR lpContactName);

struct StartOle {
    StartOle() { CoInitialize(NULL); }
    ~StartOle() { CoUninitialize(); }
} _inst_StartOle;

void main()
{
   HRESULT      hr = S_OK;
   BSTR      bstrDomainDNSName;

   // Get Domain Name
   hr = GetDomainName(&bstrDomainDNSName);
   printf("Domain DNS Name: %S\n", bstrDomainDNSName);

   // Change Contact "John Smith" e-mail address in "User1" mailbox contact folder
   // TODO: change Username and Contact full name
   hr = ChangeContacts(bstrDomainDNSName, "User1", "john smith");
}

//////////////////////////////////////////////////////////////////////////////////////////////////
// ChangeContacts
//
// Params:
//         [in] BSTR  bstrDomainName   Domain DNS Name
//         [in] LPSTR lpUser      Username
//         [in] LPSTR lpContactName   Full Name of a contact to be changed
// Output:   HRESULT
// Purpose:   Change a contact's e-mail address based on its full name.
/////////////////////////////////////////////////////////////////////////////////////////////////
HRESULT ChangeContacts(BSTR bstrDomainName, LPSTR lpUser, LPSTR lpContactName)
{
   HRESULT hr = S_OK;
   int iRecCount = 0;

   _bstr_t szConnString = "file://./backofficestorage/" + (_bstr_t)bstrDomainName + "/MBX/" + (_bstr_t)lpUser + "/Contacts";
   char ContactFullName[100];

   try {
      _ConnectionPtr   pConn(_uuidof(Connection));
      _RecordsetPtr   pMyContacts(_uuidof(Recordset));
      IPersonPtr      pPerson(_uuidof(Person));
      IDataSourcePtr   pDsrc;

      pConn->Provider = "Exoledb.DataSource";

      hr = pConn->Open(szConnString, "", "", 0);
      if (FAILED(hr))
      {
         printf("Open Connection Failed\n");
         return hr;
      }

      if (pConn->State == adStateOpen)
         printf("Connection Opened\n");
      else
      {
         printf("Connection Failed\n");
         return hr;
      }

      _bstr_t strSQL = "Select \"DAV:displayname\", \"DAV:href\" from scope ('shallow traversal of \""+ szConnString + "\"')";

      hr = pMyContacts->Open(strSQL,
                     pConn->ConnectionString,
                     adOpenForwardOnly,
                     adLockOptimistic,
                     0);
      if (FAILED(hr))
      {
         printf("Open Contacts Failed\n");
         return hr;
      }

      printf("Open Contacts: \n");

      iRecCount = pMyContacts->RecordCount;

      if (iRecCount == 0)
      {
         printf("No Contacts Found\n\n");
         if (SUCCEEDED(hr = pMyContacts->Close()))
            printf("Close Contacts\n");
         if (SUCCEEDED(hr = pConn->Close()))
            printf("Close Connection\n");
         return hr;
      }

      hr = pMyContacts->MoveFirst();
      if (FAILED(hr))
      {
            printf("MoveFirst Failed\n");
            return hr;
      }

      for (int i = 0; i < iRecCount; i++)
      {
         FieldsPtr pFlds = pMyContacts->GetFields();
         FieldPtr pFld = pFlds->GetItem("DAV:href");

         hr = pPerson->get_DataSource(&pDsrc);

         hr = pDsrc->Open((_bstr_t)pFld->Value,
                  NULL,
                  adModeReadWrite,
                  adFailIfNotExists,
                  adOpenSource,
                  "",
                  "");

         sprintf(ContactFullName, "%s %s", (char *)pPerson->FirstName, (char *)pPerson->LastName);

         // StrCmpI is not case-sensitive
         if (!StrCmpI(ContactFullName, lpContactName))
         {
            // TODO: replace with the appropriate e-mail address
            pPerson->Email = "JohnSmith@somewhere.com";
            // save changes
            hr = pDsrc->Save();
            if (SUCCEEDED(hr))
               printf("Contact changed\n");
            else
               printf("Failed to change contact\n");
            break;
         }

         printf("\n");
         hr = pMyContacts->MoveNext();
         if (FAILED(hr))
         {
            printf("MoveNext Failed\n");
            return hr;
         }

         pFlds = NULL;
         pFld = NULL;
      }

      hr = pMyContacts->Close();
      if (FAILED(hr))
      {
         printf("Close Contacts Failed\n");
         return hr;
      }
      else
         printf("Close Contacts\n");

      hr = pConn->Close();
      if (FAILED(hr))
      {
         printf("Close Connection Failed\n");
         return hr;
      }
      else
         printf("Connection Closed\n\n");

      return hr;

   }
   catch(_com_error e)
   {
      printf("HResult = %x\n", e.Error());
      printf("%S\n", e.Description());
      return hr;
   }
}

//////////////////////////////////////////////////////////////////////////////////////////////////
// GetDomainName
//
// Params:   [out] BSTR * bstrDomainName
// Output:   HRESULT
// Purpose: Retrieve the Domain DNS name.
/////////////////////////////////////////////////////////////////////////////////////////////////
HRESULT GetDomainName(BSTR * bstrDomainName)
{
   HRESULT hr = S_OK;
   IADsADSystemInfo *pADsys;

   hr = CoCreateInstance(CLSID_ADSystemInfo,
                    NULL,
                    CLSCTX_INPROC_SERVER,
                    IID_IADsADSystemInfo,
                    (void**)&pADsys);

   hr = pADsys->get_DomainDNSName(bstrDomainName);

   if (pADsys)
      pADsys->Release();
   return  hr;
}

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Related Topics

A template demonstrating how to create a Contact application is available on the MSDN Exchange site at:

http://msdn.microsoft.com/downloads/default.asp?URL=/code/sample.asp?url=/msdn-files/027/001/474/msdncompositedoc.xml

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Building Real-Time Collaboration Applications

Microsoft® Exchange 2000 Server Instant Messaging Service (IM) provides a powerful platform that allows users to communicate with each other through real-time conversations and to monitor each other’s online status.

The conference technology provider (CTP) is the component of Exchange Conferencing Server that provides the technologies required to host online conferences. The CTP also creates the conferencing experience for the user in a client browser.

Read the following sections to learn more about delivering Instant Messages and developing a conference technology provider.

Delivering Instant Messages

Developing a Conference Technology Provider

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Delivering Instant Messages

Microsoft® Exchange 2000 Server Instant Messaging Service (IM) is a powerful platform that enables two individuals to communicate in real-time through the use of a chat window. Exchange 2000 Server integrates instant messaging capabilities into the corporate enterprise and interacts with the Microsoft® Active Directory™ for user information and online presence information.

The topics in this section describe how to deliver instant messages.

Introduction

Before You Start

Concepts and Architecture

Programming Tasks

Example Code

Related Topics

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Introduction

This documentation describes the features in Microsoft® Exchange 2000 Server Instant Messaging Service (IM). For last-minute changes and corrections to this documentation, see the release notes for Instant Messaging.

Exchange IM allows users to communicate with each other through real-time conversations and to monitor each other’s online status.

Presence Information

Presence information is the online status of an IM contact. A contact’s status can be one of the following: Offline, Online, Busy, Be Right Back, Away, On The Phone, or Out To Lunch.

You can query for a contact’s status or continuously receive this information through notifications sent by the service when there is a status change. Presence information is available for all contacts contained in a contact list.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Before You Start

The topics in this section provide information you should know before you start programming Instant Messaging Service (IM) applications.

Getting Started

Development Environment

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Getting Started

The Microsoft® Exchange 2000 Server documentation setup installs the client component files into its Support directory. The client component files consist of the following:
  • msimcntl.dll This file contains the Microsoft® ActiveX® controls that provide the Exchange Instant Messaging Service (IM) user interfaces for the Contact View and Message View controls.
  • msimhost.exe This executable file provides the IM client services and exposes interfaces for IM services, contacts, and message sessions.
  • msimmsgr.dll and msimnetc.dll These files provide IM client protocol services.

The Exchange 2000 Server documentation setup registers these client component files during the setup process. To distribute these files, you must register them on the client computer. To register the client component files
  1. Copy the files from the server’s Support directory to the client computer.
  2. Register each of the three .dll files from the command prompt using the regsvr32 command. For example:
    C:\> regsvr32 <your install path>\msimcntl.dll
  3. Register the executable file using the regserver command. For example:
    C:\> <your install path>\msimhost.exe /regserver

Before you remove the client component files, you must unregister them on the client computer.

To unregister the client component files

  1. Unregister each of the three .dll files from the command prompt using the regsvr32 –u command. For example:
    C:\> regsvr32 -u <your install path>\msimcntl.dll
  2. Unregister the executable file using the unregserver command. For example:
        C:\> <your install path>\msimhost.exe /unregserver

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Development Environment

The following sections provide information about the Instant Messaging Service (IM) development environment and the programming languages used for delivering Instant Messages.

Working with VBScript

Working with Visual Basic

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Working with VBScript

Microsoft® Visual Basic® Scripting Edition (VBScript) is a scripting language that can only access the functionality of Component Object Model (COM) objects that support the IDispatch interface. Because all type checking is performed at run time, you do not need to include any type information.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Working with Visual Basic

To start working immediately in a Microsoft® Visual Basic® development environment, you only need to add references to the appropriate type libraries. The type libraries are required by Visual Basic to perform v-table binding and marshaling of arguments when required.

For a list of type library names to add to your project, see Adding References to Appropriate Type Libraries

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Adding References to Appropriate Type Libraries

The following table lists the type library names for the various Component Object Model (COM) components that are used to create applications for Microsoft® Exchange 2000 Server Instant Messaging Service (IM) in Microsoft® Visual Basic®. The type libraries act essentially as binary header files for these components, providing the type information necessary for the Visual Basic compiler to create instances of the COM classes, perform v-table binding to the COM interfaces on the objects, and resolve enumeration member names. The type libraries also contain various constants that can be used to simplify development with these components.

COM Components Type Library Names

Type library display name | Type library name | COM component | Remarks
MSIM Control 1.0 Type Library | MSIMCNTLLib | MSIMCntl.dll | Include this library if you plan to include the Contact View, Message View, or both user interfaces in your application.
Microsoft Exchange Instant Messaging Client 1.0 Type Library | MSIMCliSDKLib | msimhost.exe (msimhost.tlb) | Exposes interfaces for MSIM Host, IM services, contacts, and message sessions.

To use these type libraries, you must add them as references to your Visual Basic project in the standard way. After you have added the component references to your project, you should be able to view the type information for the corresponding component.

You can also use only the IDispatch interface on COM objects. In this case, you do not have to set references in your Visual Basic project to the various component type libraries. Instead, you create instances of the various COM classes by using the programmatic identifier with the CreateObject method. When you do this, performance of your application suffers because all access to the object is through the IDispatch interface.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Concepts and Architecture

The topics in this section describe the general programming principles for programming Instant Messaging Service (IM) applications.

Client Components

Contact View Control

Instant Messaging Host Object

Message View Control

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Client Components

The Instant Messaging Service (IM) documentation provides two Microsoft® ActiveX® controls in MSIMCntl.dll, and a collection of interfaces contained in MSIMHost.exe. Each of the ActiveX controls is used to manage a client view. The Contact View control manages lists of contacts as well as actions that can be performed on those lists; the Message View control manages the sending of text-based messages between contacts. The interfaces contained in MSIMHost.exe are used to manage Contact, List, and Session objects.

The ActiveX controls provide basic user interface and functionality for IM and can be used within a custom application. For example, embedding the MSIMContactView control in a Web page provides the user with an IM contact list and access to IM features. The ActiveX controls use the MSIMHost executable file to access the IM service. The following illustration summarizes the IM architecture.

Related Topics

  • Contact View Control
  • Message View Control
  • Instant Messaging Host Object

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Contact View Control

The Microsoft® Exchange 2000 Server Instant Messaging Service (IM) Contact View Control displays and manages lists of contacts. The control provides a user interface in the form of a self-contained contact list in a tree view that contains two top-level nodes: online contacts and offline contacts. Contacts created with the IM Contact View Control are automatically added to the user’s contact list. The control also provides an extensible context menu that contains actions relevant to the contact list.

The IMSIMContactView Interface defines a set of properties and methods that are used to determine how the contact list will be displayed. For example, contacts can be grouped into the two top-level nodes, or offline contacts can be filtered out altogether.

Lists

There are four types of lists:

  • Contact. The Contact list is the collection of contacts on which a user can perform actions and monitor presence information.
  • Allow. The Allow list is the collection of contacts that are allowed both to send instant messages to a user and to see the user’s presence information. Only one Allow list exists for a user.
  • Block. The Block list is the collection of contacts that are not allowed to send a user instant messages or to see the user’s presence information (the user appears as offline to all contacts on the Block list). Only one Block list exists for a user.
  • Reverse. The Reverse list is the collection of contacts that have added the user to their Contact list. Contacts are added to this list automatically by the IM service when a contact adds the user to a Contact list. Only one Reverse list exists for a user.

The IM service creates one persistent Contact list that continuously maintains contacts—even if a user logs off from the service. You can create up to 96 additional Contact lists, but these additional lists only exist while a user is logged on to the IM service.

Allow, Block, and Reverse lists are created automatically by the service. A contact can only exist on the Allow list or on the Block list, not on both simultaneously. After a contact has been moved to an Allow or Block list, the contact will appear as such on each Contact list created.

Context Menu

The IM Contact View Control provides a context menu for actions that can be taken on a selected contact. The control provides default actions, such as Send an Instant Message or Send an E-Mail Message. These actions are context-specific; if an action cannot be performed on a contact, the menu option is unavailable.

The context menu can be modified by adding custom actions to the menu or by changing the default behavior of actions.

Related Topics

  • Using the Contact View Control on a Web Page
  • Extending the Context Menu

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Message View Control

The Microsoft® Exchange 2000 Server Instant Messaging Service (IM) Message View Control provides a window that displays the following elements:

  • Current Participants list displays all of the contacts that are currently participating in the messaging session. The control manages this list automatically.
  • Available to Join list displays all of the contacts that can be added to the messaging session. This list is typically the local user’s default contact list, but could also be a custom list provided by an application.
  • Conversation History pane displays the message history starting at the time that the control was initiated on the local client for a particular session. If the control is initiated in the middle of a conversation (the user is invited into an existing conversation), the history will not include any messages exchanged before the control was initiated.
  • Outgoing Message pane displays the message that the user types and allows the user to determine the text font and color.
  • Status Message pane displays the status of the session. Status includes information such as when the last message was received, or who is currently typing a message.

The IM Message View Control can be used by a custom application or embedded directly in a Web page.

Related Topics

  • Using the Message View control on a Web page
  • Displaying the Message View control for an Incoming Instant Message

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Instant Messaging Host Object

The Microsoft® Exchange 2000 Server Instant Messaging Service (IM) Host object provides a collection of interfaces that makes it possible to develop custom client applications that access the IM service. A custom application can use the interfaces exposed by the MSIMHost object within a Microsoft® Visual Basic® or Microsoft® Visual C++® application to perform the following actions:

  • Establish an IM session connection to an IM server.
  • Create and access contacts and collections of contacts.
  • Create and manage IM sessions between contacts.
  • Send invitations to Microsoft® NetMeeting®.
  • Register for events such as status changes, incoming messages, incoming invitations, or service state changes.
  • Create in-process windows that can host user interfaces and controls.

The MSIMHost executable file is deployed and run on the local user’s workstation. This provides the local user with the services needed to receive incoming notifications from the IM service. While running, MSIMHost displays an icon in the status notification area that the user can use to log on to or log off from the IM service.

The MSIMHost object provides the methods necessary to create IM service sessions with the Exchange IM service, and to create windows to host controls for an application. The following diagram outlines IM Host objects.

Service

The IIMService Interface provides properties and methods that allow access to IM options, such as creating contacts and contact lists, creating IM sessions, and setting the state of the user.

Contacts

An IM contact is typically a user that has been enabled to use the IM service and is addressable by an IM address. A Contact object is created for the user and can be used by an application as an individual Contact object, or added to an IMContacts collection (Contact list). Adding a contact to a list subscribes the user to the contact’s presence information notifications. The IIMContacts Interface provides properties and methods for each contact; the IIMContact Interface provides properties and methods for a contact list.

Sessions

The properties and methods contained in the IIMSession Interface manage the actions performed in an IM session, such as inviting a contact to join a session, or sending text to another contact.

Windows

The properties and methods defined in the IMSIMWindow Interface determine the appearance and actions of a window that hosts an Microsoft® ActiveX® control. An MSIMWindow object can host the MSIMContactView or MSIMMessageView controls, or a custom ActiveX control.

Events

Events are generated in response to an action performed by a user or an application, such as a user changing online status. A custom application can intercept an event and provide custom behavior for the action.

Related Topics

  • Inviting a Contact to Join a Microsoft® NetMeeting® session

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Example Code

The topics in this section provide example code in Microsoft® Visual Basic® on aspects of programming Instant Messaging Service (IM) applications.

Using the Contact View Control on a Web Page

Using the Message View Control on a Web Page

Extending the Context Menu

Displaying the Message View Control for an Incoming Instant Message

Changing a Local User's State

Sending a Contact a Text Message

Inviting a Contact to Join a Microsoft Netmeeting Session

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Using the Contact View Control on a Web Page

The Contact View Control is a Microsoft® ActiveX® control that can be embedded in a Web page using the HTML <object> tag. The Service Property sets the service provider for the control. The List Property sets the list to be used. If no List Property is set, a new (non-persistent) list is created.

<html>
<head></head>
<body STYLE="font-family:'MS SANS SERIF';font-size:12">

   <object
      classid=CLSID:B06EDBC7-287D-405C-A899-9C7F8358EF26
      codeType=application/x-oleobject
      width="100%"
      height="100%"
      id=MSIMContactView
      name=MSIMContactView VIEWASTEXT>
      <param name="Service" value=0>
      <param name="List" VALUE="$$Messenger\Contact">
      <param name="FilterOffline" value=True>
      <param name="Group" value=False>
   </object>
</body>
</html>

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Using the Message View Control on a Web Page

The Message View Control is an Microsoft® ActiveX® control that can be embedded in a Web page using the HTML <object> tag. The Service Property sets the service provider for the control.

<html><head>
<title>MessageView Control Test Tool</title>
<meta content="text/html; charset=unicode" http-equiv=Content-Type>
<meta content="MSHTML 5.00.2920.0" name=GENERATOR></head>
<body bgColor=peachpuff>
<table style="WIDTH: 100%" width="100%">
  <tbody>
  <tr>
    <td align=left vAlign=top>
      <object classid=clsid:528B6917-4DED-43F1-B56C-35A1519129CA
      codeType=application/x-oleobject id=MSIMMessageView
      style="BORDER-BOTTOM: 2px inset; BORDER-LEFT: 2px inset; BORDER-RIGHT: 2px inset; BORDER-TOP: 2px inset; HEIGHT: 457px; WIDTH: 625px"
      VIEWASTEXT>
      <param name="AvailableList" value="$$Messenger\Contact">
      <param name="StatusText" value="Status Initial">
      <param name="MessageText" value="Initial Text">
      <param name="Service" value="1">
      <param name="AutoLogon" value="0"></object><br>
    </td>
    <td align=left vAlign=top></td></tr></tbody></table>
</body>
</html>

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Extending the Context Menu

To add custom commands to the context menu, call the IMSIMContactView::AddMenuItem method from the DMSIMContactViewEvents::OnMenuRequest event. The AddMenuItem method associates a unique identifier to the added menu item so that when the user selects the added menu item, an OnMenuSelect event is fired with this identifier. The custom commands will execute from the DMSIMContactViewEvents::OnMenuSelect event.

VBScript

Dim Cmd1
Dim Cmd2

SUB MSIMContactView_OnMenuRequest(BYVAL vSelected, BYREF pfDefaults)
   Dim Sep
   Cmd1 = MSIMContactView.AddMenuItem("Test Item 1")
   Sep  = MSIMContactView.AddMenuItem("")     'Inserts a menu break
   Cmd2 = MSIMContactView.AddMenuItem("Test Item 2")
End Sub

Sub MSIMContactView_OnMenuSelect(BYVAL vSelected, BYVAL lCmd)
   If lcmd = Cmd1 then
      msgbox "You selected command 1"
   elseif lcmd = Cmd2 then
      msgbox "You selected command 2"
   end if
End Sub

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Displaying the Message View Control for an Incoming Instant Message

The DIMServiceEvents::OnNewSessionRequest event fires in response to a request to start a new Instant Messaging Service (IM) session. From this event, create a IMSIMHost::HostWindow to host the Message View Control.

Visual Basic

Public WithEvents oIMServ As MSIMCliSDKLib.MSIMService
Public WithEvents oIMApp As MSIMCliSDKLib.MSIMHost

Private Sub Form_Load()
     On Error Resume Next   'Don't stop execution, continue on next line
Err.Clear

     Set oIMApp = CreateObject("MSExchangeIM.MSIMHost")
     Set oIMServ = oIMApp.CreateContext("Default", 0)

     If Err.Number <> 0 Then MsgBox "Error: " & Err.Description  'Display error message
End Sub

Private Sub oIMServ_OnNewSessionRequest(ByVal pContact As Object, ByVal pIMSession As Object, pfHandled As Variant)
     If Not pfHandled Then
          Dim oMsgWnd As IMSIMWindow
          Dim oMsgView As Object

          Set oMsgWnd = oIMApp.HostWindow("MSExchangeIM.MSIMMessageView", 0, True)

          If Not (oMsgWnd Is Nothing) Then
               Set oMsgView = oMsgWnd.object

               oMsgView.AvailableList = "$$Messenger\Contact"
               oMsgView.Invite pIMSession
               pfHandled = True
               oMsgWnd.Show
          End If
     End If
End Sub

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Changing a Local User's State

A local user’s online status can be changed on a Web page by calling the SetLocalState method.

<html>
<head>
<title>Status</title>
</head>
<body>

   <nobr>
      <div onmouseover="this.style.color='navy'"
      onmouseout="this.style.color='slategray'"
      style="COLOR: slategray; FONT-FAMILY: Arial; FONT-SIZE: 10px; FONT-WEIGHT: bold; PADDING-TOP: 5px; WIDTH: 150px">
      My status is

         <span id="txt_localstate"
         style="DISPLAY: inline; MARGIN-LEFT: 4px; VerticalAlign: Middle"></span>

         <select id=lstLocalState name=lstLocalState align="top"
               style="COLOR:    navy;
               FONT-FAMILY: Arial;
               FONT-SIZE: 10px;
               WIDTH: 110px">
            <option value="2" selected>Online</option>
            <option value="10">Busy</option>
            <option value="14">Be right back</option>
            <option value="34">Away</option>
            <option value="50">On the phone</option>
            <option value="66">Out to lunch</option>
            <option value="6">Invisible</option>
         </select>
      </div>
   </nobr>

   <object
      CODEBASE="msimcntl.cab#Version=1,0,0,001"
      classid=CLSID:B06EDBC7-287D-405C-A899-9C7F8358EF26
      codeType=application/x-oleobject
      width="100%"
      height="100%"
      id=MSIMContactView
      name=MSIMContactView VIEWASTEXT>
      <param name="Service" value=0>
      <param name="List" value="$$Messenger\Contact">
      <param name="FilterOffline" value=False>
      <param name="Group" VALUE=True>
      <param name="ShowLogonButton" VALUE="1">
   </object>
</body>

<script language="VBSCRIPT">

sub GetState()
   on error resume next
   DIM strState, strDescr
   DIM iState

   'get the current state
   MSIMContactView.GetLocalState iState, strState, strDescr
   'msgbox cstr(iState)
   'change the drop down list
   'if we're not logged in then say so, otherwise show the state drop list
   if iState = 1 then
      txt_localstate.innerHTML = "not <span style='cursor:hand;' onclick='MSIMContactView.Logon();'> <u>logged in</u></span>."
      txt_localstate.style.display = "inline"
      lstLocalState.style.display = "none"
   else
      txt_localstate.innerHTML = ""
      txt_localstate.style.display = "inline"
      lstLocalState.style.display = "inline"
      lstLocalState.value = iState
   end if
end sub

sub lstLocalState_onchange()
   on error resume next

   MSIMContactView.SetLocalState CInt(lstLocalState.value), "", ""

   if err.number <> 0 then
      msgbox "An error occured: " + err.description
      err.clear
   end if

end sub
</script>
</html>

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Sending a Contact a Text Message

The following example demonstrates how to send a text message using the IIMSession::SendText method. For additional information on the header elements, see SendText.

Visual Basic

Dim host as MSIMHost
Dim service as MSIMService

Private Sub cmdSend_Click()
     Set host = CreateObject("MSExchangeIM.MSIMHost")
     Set service = host.createContext("Default", 0)

     Const strMsgHeader As String = "Mime-Version: 1.0" & vbCrLf & "Content-Type: text/plain; charset=UTF-8" & vbCrLf & vbCrLf

     Dim session As IIMSession
     Dim cookie As Long
     Dim msgType As IM_MSG_TYPE
     Dim message As String

     ' msgType could also be IM_MSG_TYPE_NO_RESULT or  IM_MSG_TYPE_ERRORS_ONLY
     msgType = IM_MSG_TYPE_ALL_RESULTS

     Set session = service.CreateIMSession("someone@microsoft.com")
     message = txtMessage.Text
     cookie = session.SendText(strMsgHeader, message, msgType)
End Sub

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Inviting a Contact to Join a Microsoft NetMeeting Session

Inviting a contact to a Microsoft® NetMeeting® session initiates a series of methods and events used to transfer IP address information and start NetMeeting on each computer. The following illustration demonstrates the methods called and events fired in this process.

To initiate a NetMeeting session, the IIMService::SendNetMeetingInvite method is called on the local client’s computer. The following example sends a NetMeeting invitation to a remote client and sets a cookie for the session.

Visual Basic

Dim NetmeetingCookie as Long

Public Sub SendNetmeetingInvitation(contact As String)
     Dim imSession As IIMSession
     Dim imContact As IIMContact
     Dim reqCookie As Long

     Set imContact = MsgrService.CreateContact(contact)
     Set imSession = MsgrService.CreateIMSession(imContact)
     NetmeetingCookie = 123 ' An arbitrary number that you'll use to identify your NetMeeting invitation process.
     reqCookie = MsgrService.SendNetMeetingInvite(imContact, NetmeetingCookie)

     Set imContact = Nothing ' Release imContact

     'Keep imSession! Don't release it. This session will be the same throughout the NetMeeting invitation process.

End Sub

The SendNetMeetingInvite Method causes the DIMServiceEvents::OnNetMeetingInviteReceived event to fire on the remote client’s computer. In the following example, the remote contact is prompted to accept or decline the invitation to join NetMeeting. If the remote contact chooses to join the NetMeeting session, the IIMService::SendNetMeetingAccept method is called on the remote client requesting the IP address from the initiating client. If the remote contact chooses to decline the NetMeeting invitation, the IIMService::SendNetMeetingCancel method would be called instead.

Visual Basic

Dim lSendCookie As Long ' will be used on the OnSendResult to check if the message was successfully sent

Private Sub MsgrSVC_OnNetMeetingInviteReceived(ByVal pIMSession As Object, _
                                                                                ByVal pContact As Object, _
                                                                                ByVal lInviteCookie As Long, _
                                                                                pvfEnableDefault As Variant)

     Dim answerType As Long
     Dim response As VbMsgBoxResult

     answerType = IM_INVITE_TYPE_REQUEST_LAUNCH Or IM_INVITE_TYPE_REQUEST_IP ' You'll request IP
     response = MsgBox(pContact.friendlyName & " is inviting you to a Netmeeting session. Accept?", _
                      vbQuestion Or vbApplicationModal Or vbYesNo, _
                      "Netmeeting Invitation")
     If (response = vbYes) Then
          lSendCookie = MsgrService.SendNetMeetingAccept(pContact, lInviteCookie, answerType)
          MsgBox "You accepted the Netmeeting invitation sent by " & pContact.friendlyName & vbCrLf
     Else
          lSendCookie = MsgrService.SendNetMeetingCancel(pContact,lInviteCookie, &H81000308)     'Send cancel message. The number is the reason for the cancel, which is a refusal.
          MsgBox "You declined the Netmeeting invitation sent by " & pContact.friendlyName & vbCrLf
     End If

End Sub

When the SendNetMeetingAccept Method sends a request for an IP address back to the local client, the DIMServiceEvents::OnNetMeetingInviteAccepted event is fired on the local client. This event starts NetMeeting on the local computer, and calls the SendNetMeetingAccept Method on the local client. This invocation of the SendNetMeetingAccept Method sends the IP address of the local client to the remote client, firing the OnNetMeetingInviteReceived event on the remote client. This causes NetMeeting to start on the remote client calling the local client’s IP address.

Visual Basic

Dim lSendCookie As Long ' will be used to check if message was successfully sent

Private Sub MsgrSVC_OnNetMeetingInviteAccepted(ByVal pIMSession As Object, _
                                               ByVal pContact As Object, _
                                               ByVal lInviteCookie As Long, _
                                               ByVal lInviteType As Long, _
                                               ByVal bstrIPAddress As String, _
                                               pvfEnableDefault As Variant)

     If (lInviteType = IM_INVITE_TYPE_REQUEST_LAUNCH Or IM_INVITE_TYPE_PROVIDE_IP) Then      'IP Provided
          If (bstrIPAddress <> "") Then
               ' Execute NetMeeting passing the IP of the callee.
               ' Me is the current form in your VB application. We need its handle for the ShellExecute call
               ShellExecute Me.hwnd, "Open", "callto:" & bstrIPAddress, 0&, 0&, 3   ' 3 = SW_SHOWMAXIMIZED)
          Else
               MsgBox "Error: IP is empty!"
          End If
     Else 'The invite type was ( IM_INVITE_TYPE_REQUEST_LAUNCH Or IM_INVITE_TYPE_REQUEST_IP )
          Dim answerType As Long
          answerType = IM_INVITE_TYPE_REQUEST_LAUNCH Or IM_INVITE_TYPE_PROVIDE_IP   ' You provide IP in this situation.
          lSendCookie = MsgrService.SendNetMeetingAccept(pContact, lInviteCookie, answerType)
          ' Execute NetMeeting waiting for a call. So, no IP is provided to the NetMeeting at this point.
          Shell("C:\Program Files\NetMeeting\conf.exe ", vbNormalFocus)
          Exit Sub
     End If

     MsgBox pContact.friendlyName & " accepted your Netmeeting invitation!"

End Sub

The following example demonstrates the DIMServiceEvents::OnNetMeetingInviteCancelled event that is fired when a remote client declines an invitation to join NetMeeting.

Visual Basic

Dim NetmeetingCookie as Long ' This was set during SendNetMeetingInvitation execution

Private Sub MsgrService_OnNetMeetingInviteCancelled(ByVal pIMSession As Object, _
                                                                                ByVal pContact As Object, _
                                                                                ByVal lInviteCookie As Long, _
                                                                                ByVal hrReason As Long, _
                                                                                pvfEnableDefault As Variant)

     ' Received if the remote client cancelled the NetMeeting invitation by calling SendNetMeetingCancel.
     ' The invitation was sent by this client using SendNetMeetingInvitation.

     ' Check if the cancellation message corresponds to the invitation sent.
     If (lInviteCookie = NetmeetingCookie) Then
          ' Display message about cancellation in the form opened to the
          ' session with the remote client.
          MsgBox  pContact.friendlyName & " didn't accept your Netmeeting invitation" & vbCrLf
     End If

End Sub

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Developing a Conference Technology Provider

The conference technology provider (CTP) is the component of Microsoft® Exchange Conferencing Server that provides the technologies required to host online conferences. The CTP also creates the conferencing experience for the user in a client browser. Conference technology providers (CTPs) integrate Exchange Conferencing Server and conferencing software developed by Independent Software Vendors (ISVs). Custom CTPs can offer calendaring support for conferences, a common end-user experience across muliple conferencing technologies, and centralized administration. The topics in this section describe how you can design and develop a CTP.

Read the following sections for more information about developing a CTP:

Introduction

Before You Start

Concepts and Architecture

Programming Tasks

Example Code

Related Topics

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Introduction

The conference technology provider (CTP) provides the technologies that enable Independent Software Vendors (ISVs) to integrate their conferencing products with the Exchange Conferencing Server component that ships with Microsoft® Exchange 2000 Server to host online conferences. By integrating their products with Exchange Conferencing Server, ISVs can offer the following benefits to their customers.

Calendaring Support for Conferences

A user can schedule and join a conference by using the calendar meeting request form in Microsoft® Outlook®. Outlook 2000 is required to schedule a meeting, but not to join the meeting. A unique URL is generated for every meeting, so a user can receive a meeting invitation and use the URL to join the conference from an older version of Outlook.

Unified End-User Experience Across Multiple Conferencing Technologies

Users often need to use multiple conferencing technologies for an online conference. For example, to review a Microsoft® PowerPoint® presentation online, users typically need an application-sharing conference technology (T.120) to share the PowerPoint application and a teleconference technology to communicate. These technologies follow different procedures for scheduling and joining meetings. Exchange Conferencing Server integrates the tasks related to scheduling and joining conferences that include different types of conference technologies. This integration simplifies the end-user experience by unifying the tasks into a single procedure (through Outlook and Exchange).

Centralized Administration

Because Exchange Conferencing Server is integrated with Exchange, users can administer the component from the familiar Microsoft® BackOffice® suite of tools.

This document assumes familiarity with the following:

  • Exchange Conferencing Server product
  • Exchange Conferencing Server documentation
  • Component Object Model (COM) technologies from Microsoft Corporation
  • Outlook and Exchange
  • Microsoft® Windows® 2000 concepts, such as the Active Directory™ directory service
  • Strong programming skills

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Concepts and Architecture

For integration with Microsoft® Exchange Conferencing Server, an ISV needs to develop a conference technology provider (CTP) specific to the product. The CTP creates the conferencing experience for the user in a client browser. To schedule a meeting, the user picks invitees from the Microsoft® Outlook® 2000 meeting request form and invites a conference resource, which is a virtual meeting room that defines the format of the meeting. An administrator can configure the conferencing resources by defining various technology-specific parameters.

To integrate a third-party product into Exchange Conferencing Server, the following components need to be developed: CTP, Active Server Pages (ASP) pages, a Microsoft Management Console (MMC) snap-in extension, and a setup program.

Conference Technology Provider

A CTP communicates with Exchange Conferencing Server through well-defined Component Object Model (COM) interfaces that implement the calendaring and scheduling functionality in Exchange and Outlook. A CTP provides the following:

  • Determines and publishes free/busy availability information for resources to help scheduling.
  • Defines conference resources, which are virtual meeting rooms, to which an administrator can associate multiple conference technology providers (CTPs), creating an integrated conferencing experience for the user. An example might be an Application Collaboration Room (maximum occupancy of 10) resource, which uses two CTPs — data conferencing and teleconferencing — to help a team of people (maximum 10) collaborate on a document. Users go to a single meeting by clicking the join conference button in Outlook. Users connect directly to the conference without needing to follow different steps for differing conferencing technologies. Then they can talk to their colleagues over the telephone, and the documents on which they want to collaborate are readily available.
  • Specifies provider-specific properties — such as the size of the virtual conference room and other properties — for resources. All of this information is stored in (and retrieved from) Microsoft® Active Directory™.

The CTP provides the integration logic for conferencing.

ASP Pages

ASP pages create the conferencing experience for the user in the client browser. Separate pages are needed for pre-join (pre-meeting), join, and post-join (post-meeting) participation.

MMC Snap-ins

MMC snap-ins provide an interface for administrators to configure resources and their properties. The interface provides a way to view and change the configuration parameters of the CTP and its resources.

Setup Program

A setup program can install the various conference technology components, registering the CTP and MMC snap-in extension with COM and with Microsoft® DirectShow®.

Read the following sections for more information about developing a CTP:

Architecture

Design Tasks

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Architecture

To develop a conferencing technology provider, you must understand the various interrelated components of Microsoft® Exchange Conferencing Server. The following diagram illustrates these various components. The role of each of the components is briefly described in the following sections.

Conference Management Service

The Conference Management Service (CMS) is the component of the Exchange Conferencing Server that enables CTPs to integrate with Exchange 2000 Server. The CMS is a free-threaded component that runs as a service and loads the CTPs registered to it as in-process components when it is started. Like a Microsoft® Windows® 2000 site, the Exchange Conferencing Server design allows no more than one CMS server to run within a zone. The CMS provides interfaces that allow a conference technology provider (CTP) to determine the zones where it is installed and retrieve values of properties that are specific to the CMS installed in each zone. For instance, the CTP can register with the ICMSZone object (the zone object) to be notified when properties are changed on the CMS or new resources are added. Therefore, conference technology providers (CTPs) need to be installed and registered with the CMS on the appropriate computers in the zones where the administrator would like to deploy the CTPs. The CTPs can use the CMS configuration object (a free-threaded, scriptable component) to obtain information about the various zones and the providers installed in the zones. If the CTP needs to communicate with other instances running on other zones, it has to use a proprietary channel — for example, Distributed Component Object Model (DCOM) — to communicate.

Conference Technology Provider

A CTP is a free-threaded Component Object Model (COM) component that implements the IConferenceTechnologyProvider interface. All CTPs registered with the Conferencing Server are loaded by CMS in process. A CTP determines the end user experience when joining, prejoining, and postjoining a meeting, in addition to determining the scheduling experience through free/busy computations and event handling.

Microsoft Management Console

To enable UI-based configuration of a CTP property per site or per resource, a Microsoft Management Console (MMC) snap-in extension must be implemented. Note that CTP properties for each Windows 2000 site are stored in Microsoft® DirectShow®, and can be configured through Active Directory™ Service Interfaces (ADSI) or Lightweight Directory Access Protocol (LDAP) from a process with the appropriate security context. Per-resource CTP properties can be configured by using ICMSResource methods.

Setup

A setup program is needed to register the various components that integrate a conferencing technology into Exchange Conferencing.

Active Server Pages

Active Server Pages (ASP) pages render the conferencing experience to the end user. The end user experience can be different for different attendees, or can be based on when an attendee joins a meeting. The CTP dynamically generates a URL to the ASP page representing the attendee experience.

Key Terminology contains a list of terms and definitions of services and resources that support the CTP.

For more information, see the Exchange 2000 SDK Conferencing Sample that illustrates how to design, build, and set up each of the components mentioned previously. The conferencing interfaces are documented in the Reference section of this SDK.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Key Terminology

Conference Management Service (CMS). The component of Microsoft® Exchange Conferencing Server responsible for the reservation and scheduling of online conferences.

Conferencing site. The administrative unit for Exchange Conferencing Server. A conferencing site is defined as a Microsoft® Windows® 2000 site that contains an Exchange Conferencing Server running the CMS.

Host server. The Exchange Conferencing Server running the active instance of the CMS.

Conference technology provider. A component of Exchange Conferencing Server that provides the technologies required to host online conferences.

Conference resource. A mailbox-enabled account created in Microsoft® Outlook® 2000 that the CMS uses to facilitate the reservation and scheduling of CTPs.

Conference calendar mailbox. The storage location in Outlook 2000 used by the CMS to support the conference format and structure, and any additional information associated with online meetings.

Global calendar mailbox. A global mailbox that contains all scheduled meeting profiles for the associated conferencing site.

MeetingID. A unique value that distinguishes meetings. The meeting ID is the same for instances of a recurring meeting and is preserved during meeting updates.

Meeting profile. A snapshot of the configuration of the meeting and all of its CTPs as of the time the meeting was scheduled.

Meeting access pages. A set of Web pages hosted by Microsoft Internet Information Services (IIS) that facilitate client access to online conferences.

Per conferencing site conference technology provider (CTP) properties. CTP attributes that are set at the conference site level. They are accessed by direct Active Directory™ Service Interfaces (ADSI) or Lightweight Directory Access Protocol (LDAP) calls on the Directory Service (DS).

Per conference resource CTP properties. CTP attributes that are set at the resource level. They are accessed by using ICMSResource interface methods.

Per conference profile CTP properties. CTP attributes that are set at the conference profile level. They are accessed by using IConferenceProfile interface methods.

Data Conferencing Service. A CTP supplied with Exchange Conferencing Server that permits the hosting of data online conferences.

Video Conferencing Service. A CTP supplied with Exchange Conferencing Server that permits the hosting of video online conferences.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Design Tasks

This section discusses the design of the components that need to be developed to integrate a conference technology into Microsoft® Exchange Conferencing Server.

For more information about conference technology provider (CTP) components, see the following topics:

The Conference Technology Provider

Security

Conference Client Browser

CTP Properties

Installation and Administration of the CTP

For background information, see the Architecture and Reference sections.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


The Conference Technology Provider

The conference technology provider (CTP) is an in-process Component Object Model (COM) component that implements the IConferenceTechnologyProvider interface. By implementing this interface and registering with the Conference Management Service (CMS) for event notifications, the CTP enables the following tasks.

The meeting organizer can:

  • View the free/busy availability of a conference resource containing the CTP.
  • Schedule a conference that involves a resource associated with the CTP.
  • Modify a scheduled conference that involves a resource associated with the CTP.

The meeting attendee can:

  • Join a scheduled conference that involves a resource associated with the CTP.
  • Pre-join a scheduled conference.
  • Post-join a scheduled conference.

The CMS can:

  • Start a scheduled conference.
  • End a scheduled conference.
  • Provide the CTP with a notification mechanism for timer and state change events.
  • Provide the CTP with a mechanism for accessing conference and attendee profiles.

The CTP can:

  • Maintain and manage the lifetime of its internal state per conference.
  • Receive notifications for registered events, and update its internal free/busy state accordingly.
  • Request republishing of the free/busy availability.
  • Accept and reject conference requests based on the CTP’s availability.

Conference Scheduling

When a Microsoft® Exchange Conferencing Server resource schedules a conference, the following occurs:

  • Microsoft® Outlook® creates the appointment item, also referred to as the meeting profile, in the resource mailbox. The CMS is registered to be notified of Exchange Conferencing resource mailbox modifications and it is notified of the change.
  • To confirm availability, the CMS calls the IConferenceTechnologyProvider::ConfirmScheduleRequest method on each of the conference technology providers (CTPs) associated with the conference resources. If any CTPs decline the ConfirmScheduleRequest call, the CMS calls IConferenceTechnologyProvider::AbortScheduleRequest on all CTPs that return successfully, and the meeting is declined. If the CTP maintains its own internal free/busy state, it needs to update its internal state as part of the ConfirmScheduleRequest and AbortScheduleRequest methods. If the internal free/busy state changes from free to busy or busy to free as a result of the update, the CTP needs to request that the CMS call the IConferenceTechnologyProvider::GetAvailability method to republish the free/busy availability. This request is accomplished by calling the IConferenceManager::AvailabilityUpdateRequest method.

If the ConfirmScheduleRequest call succeeds, all CTPs accept scheduling of the meeting, then the CMS copies the meeting to the global calendar mailbox for the conferencing site.

  • After the CMS has copied the meeting to the global calendar mailbox, it performs the following actions for all CTPs associated with the resources used in the meeting. Note, however, that the actions do not necessarily happen in the following order because the two actions occur on two independent threads.
    • The CMS calls the IConferenceTechnologyProvider::GetAvailability method for each of the CTPs associated with the resource, passing the method a list of resources and the time period for the meeting. The CTP is expected to compute the free/busy availability during this time period and set the value in a bit array. Note that the CTP does not update its internal free/busy availability by using this method.
    • The CP_CREATE event is fired and the notification callback on each of the CTPs associated with the resource is called. The event is fired when the meeting is copied to the global calendar store. A pointer to the IConferenceProfile interface, which contains the details of the meeting that was created, is passed to this event notification callback.

Conference Cancellation

Whenever a conference is canceled, the CMS fires the CP_DELETE event. The callback method of each CTP that registered to receive notification for the event is called. If the CTP maintains its own internal free/busy state, it needs to update its internal state while handling the CP_DELETE event. If the internal free/busy state changes from busy to free as a result of the update, the CTP needs to ask the CMS to call the GetAvailability method to republish the free/busy availability. This request is accomplished by calling the IConferenceManager::AvailabilityUpdateRequest method.

Conference Profile Modification

Whenever a conference is modified, the CMS fires a CP_MODIFY event. Note that a CP_DELETE event followed by a CP_CREATE event can be fired instead of CP_MODIFY. Because the CTP registers to be notified of such events, its event handler is called and passed a pointer to the conference profile (the IConferenceProfile interface). The GetAvailability method is also called separately on the CTP. If the CTP maintains its own internal free/busy state, it needs to update its internal free/busy state as part of the ConfirmScheduleRequest and AbortScheduleRequest methods, which are called before CMS fires the CP_MODIFY event.

Conference modification is handled the same way as conference scheduling. An example of a modification to the conference profile is extending the conference time or changing a meeting’s resource.

Free/Busy Computation for Resources

When scheduling a meeting, users can look up the availability of a resource. This process is similar to the way users view the availability of the people with whom they schedule meetings. These processes are similar because the CMS publishes the free/busy information to the same public folder in Exchange that Outlook accesses to obtain attendee availability information. The CMS obtains this information from the CTP whenever a meeting is scheduled or changed, as previously described in the Conference Scheduling section.

To illustrate this concept with an example, the Data Conferencing Service provided with Exchange has a CTP property that defines the total number of concurrent users of conferences. It also defines a size property on the resources. The CTP computes free/busy availability for a given time interval by totaling the size parameter for all resources used in data conferences during that time interval. All resources whose sizes are greater than the available capacity are marked as busy for that time interval. The available capacity is computed by subtracting the sum of the size property for all resources used for the time interval from the CTP property, which defines the total number of concurrent users.

Changing the CMS Host Server

An administrator can change the host server for the CMS using the Properties dialog box (a Microsoft Management Console (MMC) snap-in) in the Exchange System Manager tool. When the host server of the CMS (and, hence, the CTP) in a certain site is changed, the following occurs:

  • On the CTP running on the old host:
    • CM_STOPPING is fired.
  • On the CTP running on the new host:
    • CM_STARTING is fired.
    • The IConferenceTechnologyProvider::StartConference method is called on all conferences that are current (that is, in progress).
    • CM_RUNNING is fired.

The CTPs need to be designed to handle changes to the host server appropriately. For example, the CTP might not need to stop ongoing conferences when a CMS (and hence the CTP) is stopped and restart them when the CMS is started. Each CTP needs to have the appropriate logic to detect this scenario when StartConference and StopConference methods are called.

Registering and Handling CMS Event Notifications

The CTP might need to handle numerous events generated by the CMS. These events involve:

  • The creation, modification, and deletion of meetings.
  • Changes to the CMS state: initializing, running, or being stopped.
  • Changes to the global calendar mailbox (CM_GLOBALMAILBOXCHANGED).

    The global calendar mailbox can be changed without stopping the CMS. When the global calendar mailbox changes, the old conference profiles are no longer valid and the CTP must release all old profile pointers. The CMS calls the StartConference method on each CTP associated with an active conference to synchronize the CTP with the conferences held in the new store.

  • Registration of the CTP with the CMS to obtain timer events at a specific time in the future.

    The timer can be set to a specific time in the future or a time relative to the current time. The timer is useful when a CTP needs to provide a different experience for attendees who join during the pre-meeting and post-meeting grace periods. It is also useful when a CTP must allocate scarce resources for the duration of the meeting only.

Starting a Conference

When the start time for a conference (the time that the conference is scheduled to start, minus any grace period) is reached, the StartConference method is called and passed the meeting ID and a pointer to the IConferenceProfile interface, which enables the CTP to obtain more details about the meeting. The CTP is expected to do the initialization work for the meeting at this time. If this method returns a failure, the client browser does not allocate a pane for the CTP.

If the CTP needs to allocate critical resources that cannot be overbooked, the CTP can use timer events to ensure that resources are allocated at the start time of the scheduled meeting, instead of allocation of resources at the start time minus the grace period. This becomes more important for back-to-back meetings that use the same conference resources.

When the CMS is stopped and restarted, it attempts to call the StartConference method on all conferences that are current. If a conference has already started, the CTP needs to have a way to detect this. If the CTP keeps track of specific state information for running meetings, this information needs to be written to the profile store so that it can be retrieved if the server shuts down and restarts.

Stopping a Conference

The StopConference method is called at the scheduled end time of the conference plus any configured grace period. The CTP needs to handle ending the conference.

Joining a Conference

When a user joins an active meeting or enters during the pre-meeting or post-meeting grace period for the meeting, the CMS calls the IConferenceTechnologyProvider::JoinRequest method on each of the CTPs. These grace periods are configurable properties on the CMS. Each CTP is expected to return a URL that can be rendered in the pane allotted for the CTP in the client browser. For more information, see the IConferenceTechnologyProvider::JoinRequest method.

Pre-Joining or Post-Joining a Conference

A user can join a conference before the start of the pre-meeting grace period (pre-join) or after the post-meeting grace period (post-join). When a user joins at either time, the CMS calls the IConferenceTechnologyProvider::PreJoinRequest method or the IConferenceTechnologyProvider::PostJoinRequest method and the CTP returns an appropriate URL for the very early or late attendees. For example, a pre-join request page for a telephone conference may contain the telephone number and access code that the client browser can dial to join the conference. For more information, see the documentation for these methods in the Reference section.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Security

An online conference is secured by restricting access to the meeting participants and the conference content.

Microsoft® Exchange Conferencing Server supports the creation of public meetings, public meetings with a password, and private meetings. Anyone with the URL for the conference can access public meetings. Public meetings with a password can be joined by anyone with the conference URL and the password for the conference. If the meeting is private, only those on the "To" line of the meeting request can access the meeting. The conference organizer can administratively restrict meeting access. The conference technology provider (CTP) requires no additional code to support this feature.

The Conference Management Service (CMS) handles the security of content for a conference. For example, the Data Conferencing Service, the CTP that permits the hosting of data online conferences, uses a Secure Sockets Layer (SSL) public certificate to authenticate users into the conference and subsequently encrypt all transmitted conference content.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Conference Client Browser

Active Server Pages (ASP) pages deliver the content the end-user sees to the client browser. The scripts for the Microsoft providers, Video Conferencing Service and Data Conferencing Service, are placed in the ExchangeServerRootDirectory/Conferencing directory. If a provider installs its ASP scripts in this virtual directory, the conference technology provider (CTP) can receive Web server change notifications. When a user joins a conference, the CTP returns the URL to the location of an ASP script. This enables the CTP to return a different ASP script based on the time the user is trying to join the conference (before, during, or after) and establish the identity of the person who is joining the conference.

An Internet Server Application Programming Interface (ISAPI) filter turns the Web server’s /Conferencing/ and /ConferencingPrivate/ roots into nonsecure or secure links in the appropriate language’s directory under ExchangeServerRootDirectory/Conferencing (for example, ExchangeServerRootDirectory/Conferencing /jpn for the Japanese-language version).

The ASP script can join, modify, or list conferences by using the conference locator object for the zone (for more information, see the IConferenceLocator interface in the Reference section). The script instantiates the Conference Management Service (CMS) administration object, identifying the zone object, and obtaining the locator object from the zone. The locator object can also be used to obtain a provider-specific interface (IDispatch interface) to call directly into the CTP object.

The following example shows how the ASP code can obtain the conference locator for the current zone.

Dim CMSAdmin
Dim CMSZone
Dim ConfLocator

...
Set CMSAdmin
Set CMSZone = Nothing
Set ConfLocator = Nothing
   ...
   CMSAdmin = Server.CreateObject("XCMSCOM.CMSConfiguration")
   Result = CMSAdmin.GetZone("", CMSZone)
   ? Check for errors and handle them?.
   Result = CMSZone.GetConferenceLocator(ConfLocator)
   ? Check for errors and handle them?
   Result = ConfLocator.GetProviderExtensions(PROVIDER_CLASS_ID)
   ? Check for errors and handle them?
   ...

The ASP scripts for the Data Conferencing Service in Dcs.asp are a good source of information about how to use conference locators.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


CTP Properties

All conference technology providers (CTPs) have a core set of properties, the MSExchCTP class properties, which each conference technology provider (CTP) receives when registering with the Conference Management Service (CMS). Each CTP can define and configure its own set of custom properties in addition to the properties derived from the MSExchCTP class. Each CTP can have per conferencing service site CTP properties, per conference resource CTP properties, and per conference profile CTP properties. The following sections describe how to create and configure each of these types of properties.

Per Conferencing Site CTP Properties

Per conferencing site CTP properties are properties whose values are visible in the CMS zone where the CTP is registered. These properties are created during CTP registration with the CMS by extending the Microsoft® Active Directory™ schema to accommodate the new class of the CTP class and its related attributes. The new CTP class must be derived from the MSExchCTP class. An example of a per conferencing site CTP property would be the maximum number of connections to the Microsoft® Exchange Conferencing Server.

The per conferencing site CTP properties are set when the CTP is registered with the CMS. To configure these properties after initial registration with the CMS, the CTP developer must provide a Microsoft Management Console (MMC) snap-in extension. This enables the CMS to detect and call conferencing site property pages for configuring the properties of the CTP. For more information, see the CTP Registration with the CMS and MMC Snap-in Extension Registration sections.

Accessing Per Conferencing Site CTP Properties

The CTP may need to access the values of its properties that are set by the administrator. For instance, the Video Conferencing Service available with Exchange 2000 Server retrieves the total number of concurrent users who are allowed to participate in video conferences while computing IConferenceTechnologyProvider::GetAvailability. The CTP will need to read the values directly from Active Directory using the Lightweight Directory Access Protocol (LDAP) or Active Directory™ Service Interfaces (ADSI) API set. For more details about how to create and configure CTP attributes using ADSI, see the Exchange 2000 Server SDK Conferencing sample.

Per Conference Resource CTP Properties

The per conference resource CTP properties are configured for each resource mailbox. Multiple resource mailboxes that use the same CTP can have their relative conferences customized differently based on the conference resource properties. The audio coder/decoder (codec) payload type is an example of conference resource CTP properties that can be set for each resource mailbox. After a meeting is created with the specific resource mailbox configuration for the contained CTPs, Exchange Conferencing Server copies the meeting profile to the global calendar mailbox. Further updates to the CTP properties at the resource mailbox scope cannot change the behavior of already-scheduled meetings.

The GetProviderPropertySet and SetProviderProperty methods of the ICMSResources interface are used to read and configure conference resource CTP properties at the resource mailbox level. To configure conference resource CTP properties using the Exchange Conferencing Server MMC snap-in, the CTP must support the ICTPSpecifyResourcePropertyPages interface on the MMC snap-in extension of the CTP. This is the same snap-in extension that is used to support conferencing site CTP properties. This interface enables the CMS to dynamically create a CTP conference resource property page for administration from within the Exchange Conferencing Server user interface (UI).

Accessing Properties of a Resource Mailbox

The CTP may need to access the property values defined on a resource when a meeting is scheduled — for example, to compute the size of a frame in a video conference.

A pointer to the resource object (ICMSResources interface) used in a meeting can be obtained from the IConferenceProfile interface. IConferenceProfile contains information about a meeting that CMS passes to the CTP in the StartConference method. The ICMSResource::GetProviderPropertySet method can be used to obtain the list of properties that the CTP defines on its resources.

Resource Modification

Meetings scheduled before a resource becomes modified remain as is — that is, they use the definitions of the resource as they were when the meetings were originally scheduled. However, the CTP can register with its zone object to be notified when resources are modified or added. For more information, see the ICMSZone interface in the Reference section of this SDK.

Per Conference Profile CTP Properties

Per conference profile CTP properties are defined and configured at the conference profile scope. The conference profile includes a snapshot of all types of CTP properties specific to a meeting appointment. These properties are only valid for the meeting for which they are specified. The IConferenceProfile::UserProperty get and put methods are used to set and obtain the CTP properties at the conference profile scope. The ProviderClassID parameter is used to uniquely identify the namespace on the conference profile where the properties are stored. In addition, the IConferenceProfile::UserProperty method enables providers to read properties from the Outlook form namespace. For more information, see the method description of the IConferenceProfile::UserProperty.

Accessing Meeting Details

If a CTP needs to retrieve information about an appointment, such as file attachments or recurrence properties, it needs to use Collaboration Data Objects (CDO) directly to retrieve the data from the appointment item. For an example showing how to obtain appointment details, see the CTP SDK. The CTP SDK is part of the Exchange 2000 Server SDK and available on MSDN.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Installation and Administration of the CTP

This section discusses the tasks associated with the administrative component of the conference technology provider (CTP), which is separate from the CTP and the Conference Management Service (CMS) run-time components, also described. The administrative component does the following:

  • Installs the CTP by registering it (and its properties) with the CMS, which includes setting the right set of properties in Microsoft® Active Directory™.
  • Provides a Microsoft Management Console (MMC) snap-in to allow users to set and view the properties of CTP.

CTP Registration with the CMS

This section assumes familiarity with Active Directory and the concept of schemas. The Active Directory™ Service Interfaces (ADSI) or Lightweight Directory Access Protocol (LDAP) application programming interfaces (APIs) are used to add the new entries in Active Directory, registering the CTP with the CMS.

To register the CTP with the CMS:

  • The in-process Component Object Model (COM) dynamic-link libraries (DLLs) that implement the CTP need to be registered with the system by using the regsvr 32 command.
  • The CTP needs to instantiate certain entries in Active Directory that enable the CMS to discover the existence and attributes of the new CTP, and to create the CTP object when CMS is started. Details of the schema for classes and attributes that need to be instantiated are explained later. When Microsoft® Exchange Conferencing Server is installed, it extends the Active Directory schema to define the core set of attribute entries that the CTP needs to set. However, if the CTP needs to define additional properties that are specific to its technology, it needs to extend the schema to define these new attributes.

The following is a sample tree hierarchy in Active Directory for the CMS and the conference technology providers (CTPs) registered with it. The classes associated with each of the objects are also shown in the tree.

+--Configuration (configuration)

+--Services (container)

¦ +--Microsoft Exchange(msExchConfigurationContainer)

¦ ¦ +--Organization 1 (msExchOrganizationContainer)

¦ ¦ ¦ +--Administrative Groups (msExchAdminGroupContainer)

¦ ¦ ¦ ¦ +--First Administrative Group (msExchAdminGroup)

¦ ¦ ¦ ¦ ¦ +--Exchange Conferencing (msExchConferenceContainer)

¦ ¦ ¦ ¦ ¦ +--3356148e-a8c5-11d2-85e9-00c04fa376eb (msExchConferenceSite)

¦ ¦ ¦ ¦ ¦ ¦ +--Exchange Video Conferencing Service (msExchIPConfContainer)

In the preceding example, the Exchange Video Conferencing Service CTP has defined and instantiated a new class named msExchIPConfContainer. The msExchIPConfContainer class inherits from the msExchCTP class.

The Microsoft® DirectShow® node under which a new CTP class can be instantiated is located under the node specified by the value of the msExchConferenceZoneBL property. This property is found efficiently by searching the node specified by

cn=SiteName,cn=sites,cn=Configuration,ConfigurationNamingContext,

where

SiteName is the Microsoft® Windows NT® site name obtained through DSGetSiteName, and ConfigurationNamingContext is the value of this property obtained by searching the top of the DirectShow tree. For more information, see the CTP SDK sample.

The properties that are defined by the msExchCTP class and need to be set when this class is created include the following:

Attribute name | Type | Description
msExchCTPProviderGUID | Unicode string | Unique ID of the provider. It is recommended that a globally unique identifier (GUID) be used for this attribute.
msExchCTPProvider-Name | Unicode string | Internal name of the provider class (restricted to 32 characters in length).
msExchCTPClassGUID | Unicode string | ID of the CTP class that the CMS uses to instantiate the CTP object.
msExchCTPSnapinGUID | Unicode string | ID of the MMC snap-in object that the CMS instantiates into MMC when the CMS is started.
msExchCTPFrameHint | Integer | The value of this property is used by browser clients as a hint for scaling the CTP frameset.
msExchCTPRequireCMSAuthentication | Boolean | Boolean value that indicates whether the CMS needs to try to authenticate (through Windows NT logon and password) the user in a conference to which external attendees are not allowed.
SystemFlags | Integer | 0 x 60000000 hexadecimal or 1610612736 decimal. This value for SystemFlags allows the DS entries of the CTP to be to be moved across zones.
CTP-Specific-Attribute1 |  | This name represents optional custom properties defined by a new CTP class.

If the CTP needs to define additional properties with conferencing site scope, then the CTP:

  • Needs to extend the Active Directory schema by defining the new attributes and by defining a new container class that inherits from the msExchCTP class and that contains the new attributes.
  • Needs to instantiate the new CTP class object in DirectShow.
  • Needs to register the new CTP class under the appropriate CMS node described previously. An LDAP Data Interchange Format (LDIF) script or ADSI methods can be used to extend the schema and register the new CTP class with the CMS. For implementation details, see the Exchange 2000 Server SDK Conferencing sample. The MSDN® Library is another good source of information about this subject.

If administrative configuration of the new CTP properties is required, an MMC snap-in extension needs to be provided for configuring the new set of attributes as part of the Exchange Conferencing Server UI.

The MMC snap-in extension for the CTP must use direct LDAP or ADSI calls to configure the conference site CTP properties.

The MMC snap-in for the CTP must be registered with the CMS. This registration is accomplished by setting the value of the CTP msExchCTPSnapinGUID attribute as the MMC snap-in GUID.

If the CTP needs to define additional properties that have resource mailbox visibility, ICMSResource interface methods can be used to define and set the new properties’ names and values. The DirectShow schema doesn’t need to be extended.

If administrative configuration of the new properties is required, an MMC snap-in extension needs to be provided. This snap-in extension is the same as the one used to configure per conferencing site CTP properties. This snap-in extension must support the ICTPSpecifyResourcePropertyPages interface. The GetPages method on that interface enables the MMC snap-in for Exchange Conferencing Server to dynamically populate a custom property page to configure the new CTP attributes for each resource mailbox. The MMC snap-in must be registered with the CMS.

If the CTP needs to define custom properties on a per conference profile basis, the IConferenceProfile::UserProperty property needs to be used to define, set, and obtain the values for the custom properties. These custom properties do not require extending the DS or creating a snap-in extension.

Finally, if the CTP does not need to define additional properties, it can instantiate an instance of the msExchCTP class and add it to the appropriate CMS node, as indicated previously.

MMC Snap-in Extension Registration

If the CTP defines new properties at the conferencing site or resource scope, and requires administrative configuration of such properties, an MMC snap-in extension UI is needed to allow users to access and change property values. The CMS automatically loads the snap-in extension of the CTP when Exchange System Manager loads the CMS. The GUID of the snap-in extension object is available from the Active Directory schema — it is one of the attributes of msExchCTP, msExchCTPSnapinGUID.

MMC is an extensible, common console framework for management applications available to ISVs. The MSDN library contains good information about how to develop MMC extension snap-ins that are application specific.

CTP Upgrade

The process of upgrading a CTP includes:

  • The existing CTP dynamic-link library (DLL) must be replaced by an updated version.
  • If the updated CTP supports new attributes on the conferencing site, the existing class schema for the CTP must be extended to support the new attributes.
  • If the updated CTP supports new attributes and needs to administratively configure the new attributes, an updated MMC snap-in extension needs to be provided.

Note that the msExchCTPProviderGUID property value must stay the same in an upgrade.

Changing CTP property values, such as msExchCTPClassGUID or msExchCTPSnapinGUID, triggers event notifications that the CMS receives and processes. The CMS, in turn, updates its internal state and loads the new CTP state.

CTP Uninstall

The process of uninstalling a CTP includes:

  • Deregistering the CTPCOMDLLs and the associated MMC snap-in extension.
  • Deregistering the CTP and the associated snap-in extension from the CMS by removing the associated DS entries from the CMS DirectShow tree.

Removal of the CTP entries from DirectShow triggers event notifications that the CMS receives and processes. The CMS reconfigures itself accordingly.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Developer Resources

This section describes tools and other developer resources that are supplemental to the Web Storage System SDK.

Web Storage System Tools

Application Security Module

Application Templates

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Web Storage System Tools

This documentation describes the features in Microsoft Web Storage System Tools for Microsoft® Exchange 2000 Server. For last-minute changes and corrections to this documentation, see the release notes for the Web Storage System Tools on the Exchange Developer Center Web site at http://msdn.microsoft.com/exchange.

The following information is provided about Web Storage System tools:

Installation and Overview

Web Storage System TreeView Control

Web Storage System Explorer

Web Storage System Event Sink Wizard

Web Storage System Workflow Configuration Scripts

Web Storage System Application Deployment Wizard

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Installation and Overview

Microsoft Web Storage System Tools are productivity enhancement tools for developing Web Storage System applications.

Tools Installation

Install the Web Storage System tools from the MSDN® Exchange Developer Center Web site at http://msdn.microsoft.com/exchange.

You can install the tools on the server running Microsoft® Windows® 2000 and on other computers. Some tools, as described later, are used on only Microsoft® Exchange 2000 Server.

To install the Web Storage System Tools

  1. Run the setup program on the Web, which installs Extools.msi on your computer.
  2. Run Exktools.msi on your computer to complete the installation.

The Exchange 2000 Server Tools Setup Wizard installs the tools in the \Program Files\Web Storage System\Tools folder.

Tools Overview

This documentation covers the following tools:

  • TreeView Control

    The TreeView Control tool is a Microsoft® ActiveX® Control for displaying and manipulating any node hierarchy in the Web Storage System. You can use this control in Microsoft® Visual Basic®, Microsoft® Visual C++®, or other COM based developer products running on a client or on Exchange 2000 Server.

Note A heavily commented Visual Basic project that manipulates the TreeView control is available. If you installed the Microsoft Exchange 2000 Server SDK, you can use modify the SDKTreeView Visual Basic project to create an application using the TreeView control. These project files are in the SDK Samples\SDKTreeView folder.
  • Web Storage System Explorer

    This explorer is a Visual Basic application that facilitates creating property and content class definitions, defining schema scope, as well as wizards that create form and event registrations. The explorer provides two views for each folder, its items and its schema. You can use this tool remotely or on a Exchange 2000 Server. This tool requires a prior installation of either Visual Basic 6.0 or later or the Microsoft® Office 2000 Developer 1.5 update.

  • Event Sink Wizard

    The Event Sink Wizard tool is a Visual Basic Add-In Wizard that creates a project of commented code for adding an event sink to respond to Exchange 2000 Server and Web Storage System events. You can use this tool on only Exchange 2000 Server.

  • Workflow Configuration Scripts

    The workflow configuration scripts tool has Visual Basic scripts to set up the essentials for a Web Storage System Workflow application. You can use this tool on only a Exchange 2000 Server that is a Domain Controller.

  • Application Deployment Wizard

    The Application Deployment Wizard tool packages Web Storage System applications for the Windows Installer. You can use this tool on only Exchange 2000 Server.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Web Storage System TreeView Control

The Microsoft Web Storage System TreeView control (Extreeview.ocx) displays a hierarchical list of node objects that correspond to folders in the Web Storage System. See TreeView Control for its API reference documentation.

This section consists of the following topics:

Introduction to the TreeView Control

Setting Up the TreeView Control

Using the TreeView Control

Related Topics

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Introduction to the TreeView Control

You can use Microsoft Web Storage System TreeView control to add, delete, and move folders in the Microsoft Web Storage System. You can implement the control in both server and client applications.

The following figure illustrates a TreeView control on a Microsoft® Visual Basic® form and how its root nodes correspond to the Web Storage System in Microsoft® Exchange System Manager.

Note A TreeView node's display name can be different from the name of the folder in the Web Storage System. For example, the "GDisc" folder in the Exchange System Manager has a display name of "General Discussion" as shown in the preceding figure.

TreeView Control Features

The following is a list of TreeView control features. You can use TreeView control features to:

  • Program a node and its collection with other treeview controls.
  • Work with multiple virtual directories in the Web Storage System. Each virtual root corresponds to a root node in the TreeView control.
  • Add, delete, and move folders.
  • Set a node to display or hide all child nodes.
  • Set a display name for a folder in your application that is independent of the Web Storage System.
  • Get the URL, parent URL, root URL, display name, and authentication information for a folder. You can have separate authentication information for each root node.
Note This control uses the UTF-8 encoding for sending requests and receiving responses from the Web Storage System. Its methods using a URL, such as DeleteResource, require that the URL passed to it be UTF-8 encoded. Because you can get the URL from the TNode object to pass to methods, it is already UTF encoded. However, the exception is the AddRootNode method, which requires no UTF-8 encoding because that URL is input from the user and is consequently UTF-8 encoded by the TreeView Control.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Setting Up the TreeView Control

The Microsoft Web Storage System TreeView Control (Extreeview.ocx) is installed by default in the \Program Files\Web Storage System\Tools\WSSExplorer directory.

To implement the TreeView control

  1. Click Components on the Project menu.
  2. Click Browse in the Components dialog box, select the folder containing Extreeview.ocx control, and then click OK.
  3. Select the control labeled EXTV on the Toolbox and draw the control on a form.
Note To use the TreeView control with the Treeview sample application, you must have the Web Storage System Tools installed. The Treeview sample application is installed with the SDK in the \Web Storage System\SDK\Samples\Treeview folder.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Using the TreeView Control

You can use the Microsoft Web Storage System TreeView control in Microsoft® Visual Basic® applications running on Microsoft® Exchange 2000 Server or on client computers.

TreeView Control Reference

The following table lists the objects and interfaces for programming the Web Storage SystemTreeView control.

API Elements | Description
EXTV Interface | The default of its fundamental methods and properties.
RootNode Collection | RootNode object and the RootNodes collection.
TNode Interface | Sets and retrieves information for any node.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Web Storage System Explorer

With the Web Storage System Explorer, you can explore folders, items, and their property values. You can create property and content class definitions and configure their schema scope. The Web Storage System Explorer also contains wizards for creating form registrations and event registrations.

This section consists of the following topics:

Introduction to the Web Storage System Explorer

Setting Up the Web Storage System Explorer

Using the Web Storage System Explorer

Related Topics

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Introduction to the Web Storage System Explorer

The Web Storage System Explorer provides a visual framework for doing the following:

  • Exploring folders, items, and properties
  • Creating property and content class definitions, and configuring their schema scope
  • Creating event and form registrations using wizards

This tool frees you from having to write ActiveX Data Objects (ADO) or OLE DB code to perform these tasks. You can use the Explorer on Microsoft® Exchange 2000 Server or on client computers.

Explorer Components

The Explorer contains the following panes:

  • The left pane, Web Storage System Hierarchy, contains the root node for a virtual directory in the Web Storage System. The virtual root can be a Exchange 2000 Server mailbox, public folder, or a new public folder tree.
  • The right pane, Detail View, contains two nodes: the schema node and the item node. The schema node expands to display the currently selected folder's schema. This node is a hierarchical view of properties used for defining property and content class definitions. The item node expands to list any items that the folder contains. Keep in mind that a content class or property definition is itself an item and will also appear in the item list.
  • The lower-right pane displays the data types and values for any selected folder, item, registration item, property definition, or content class definition.

File Menu and Right-Click Options

The File menu lists options for creating folders, items, definitions, and registrations. These options also appear when right-clicking folders, items, and other elements in the Explorer. Additional options, such as deleting, refreshing, and listing property values, appear when applicable.

If you want to change the source Web Storage System URL, click Connect To from the File menu.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Setting Up the Web Storage System Explorer

Note The Web Storage System Explorer requires a prior installation of either Microsoft® Visual Basic® 6.0 or later or the Microsoft® Office 2000 Developer 1.5 update. You can also install the latest Visual Basic run-time files by following the instructions on http://support.microsoft.com/support/kb/articles/Q235/4/20.asp (a knowlege base article).

To Run the Web Storage System Explorer

  1. Click the Start button, point to Programs, Web Storage System SDK, and then Web Storage System Tools.
  2. Click Web Storage System Explorer.
  3. In the Authorization dialog box, enter your username, password, and the root URL to the mailbox store, public folders, or public folder tree.
Note The URL becomes UTF-8 encoded for sending in an HTTP request to Microsoft® Exchange 2000 Server.

The following table lists examples of valid URLs to use with the Explorer.

Web storage system URL | Description
http://server1/exchange/username/ | A mailbox store.
http://server1/public/ | The default public folder used by MAPI clients.
http://server1/PFT1/ | A new public folder tree, established as a Virtual Directory.
https://serverS/stocktrade/ | A URL to a secured server.
http://server1/public/non_ipm_subtree/schema/ | The global Web Storage System schema definitions.
Note: Private stores, such as a mailbox, do not initially have global schema definitions.

The URL can continue down the hierarchy to the node you want to work with. For example, to work with the public folder Poll, enter http://server1/public/Poll.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Using the Web Storage System Explorer

The Web Storage System Explorer is a useful tool for managing the Web Storage System.

Typical uses for the Web Storage System Explorer include the following:

  • Creating folders and items.
  • Exploring property values in the Explorer's lower-right pane.
  • Designing schema for applications. Schema comprises the property and content class definitions used by Web Storage System applications. The Schema Tutorial describes schema design tasks and how to create schema and configure its scope. A schema's scope is important because it determines how its properties are made available to applications and searches.
  • Creating form and event registrations.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Schema Design Tasks

You can group property definitions according to functionality, purpose, or any business logic and list them in a content class definition. Doing so has a dynamic result: every item in the Web Storage System has the DAV:contentclass property. This property specifies the item's content class. When you specify an item's content class, you will automatically obtain fields on that item for each property defined in that content class.

Schemas are primarily used to provide a mechanism for schema-aware applications to discover the names of content classes and their associated properties. Schemas also include settings that determine the scope of where the search engine and applications should look for schema definitions.

Developing schemas for your Web Storage System applications involves the following tasks:

  • Determining a namespace name to prefix the names of your content classes and properties. A namespace name is typically a Uniform Resource Identifier (URI). Many corporations use their URL to their domain to assure uniqueness. For example the Microsoft security namespace prefix is http://schemas.microsoft.com/exchange/security/. For more information about namespaces and property names, see Web Storage System Item Properties in the Microsoft® Exchange 2000 Server SDK.
  • Creating application and schema folders according to your business logic. You can create, delete, and rename folders using the Explorer. A schema folder is a folder reserved for only schema definitions; however, you can have both application and schema definition items in the same folder.
  • Creating content class and property definitions using the Explorer.
  • Specifying settings for schema scope using the Explorer.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Schema Tutorial

This tutorial contains step-by-step examples for setting up a schema for a Web Storage System application, covering the following tasks:

  • Creating property definitions
  • Creating content class definitions
  • Setting schema scope
  • Testing the schema

First, create an application folder and a schema subfolder. To create a folder, right-click its parent folder in the Web Storage System hierarchy and then click Create Folder.

Preparation

To follow the tutorial, create a folder named Applications with two subfolders, AppA and AppB. Then create a subfolder named Schema in both AppA and AppB. The hierarchy should be as follows:

Applications

—AppA

——Schema

—AppB

——Schema

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Creating Property Definitions

This tutorial example creates two simple properties: color and quantity.

To Create a Property Definition

  1. Select the AppA schema folder.
  2. In the Schema Detail View pane, right-click Property Definitions.
  3. From the pop-up menu, click Add Property Definition. A Property Definition (New) dialog box appears.
  4. In the Definition name text box, specify the complete namespace and property name. For this tutorial, the property is named color, and belongs to the urn:schemas:microsoft-com:sample1: namespace, so the full name is urn:schemas:microsoft-com:sample1:color.
  5. In the Save as item name text box, specify a name for the item that will contain the property definition, the naming scheme being your choice. This tutorial uses p_color.def.
  6. Specify a Data Type. Specify the string for the color property.
  7. Optionally, specify a Version and the Default values.
  8. Optionally, click Advanced for advanced options.
  9. If you want the property indexed so it can be indexed by the Structured Query Language (SQL) Create Index command, check the Is Indexed check box.
  10. Optionally, specify any other advanced options.
  11. Click OK.
  12. Repeat this procedure and create a property definition for the urn:schemas:microsoft-com:sample1:quantity property, with an item name of p_qty.def and a number data type.

The Explorer creates the property definition. Right-click the definition for a pop-up menu of editing choices.

Note: The content class for a property definition item itself is required to be urn:content-classes:propertydef, which is set automatically by the Explorer.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Creating Content Class Definitions

A content class defines the purpose or content of an item by containing as its elements a list of properties appropriate for that purpose or content. Content classes imply a set of semantic requirements for the item. For example, an item with the content class urn:content-classes:message can be processed accordingly by messaging and non-messaging applications.

This tutorial example creates a sample content class property named "urn:content-classes:microsoft-com:sample1."

To Create a Content Class Definition

  1. Select the AppA schema folder.
  2. In the Schema Detail View pane, right-click Content Class Definitions.
  3. From the pop-up menu, click Add Content Class Definition.
  4. For the Definition name text box, specify the complete content class name. For this tutorial, the content class is named urn:content-classes:microsoft-com:sample1.
  5. For the Save as item name text box, specify a name for the item that will contain the content class definition; the naming scheme being your choice. This tutorial uses cc_sample1.def.
  6. Click the Properties tab.

    Use this tab to add properties as elements in a content class definition. This tab has two panes. The top pane lists all property definitions that have been defined in the selected schema folder. The bottom pane shows properties that have been added as elements to the content class definition.

  7. Select urn:schemas:microsoft-com:color in the list of available properties and click Add. Also add urn:schemas:microsoft-com:quantity.
  8. Click OK.

Other Definition Options

The following table describes the other tabs used for creating a content class definition.

Tab | Content class configurations
Expected CC | Use this tab for creating a list of other content classes that should be automatically attributed to a folder whenever that folder is set to the content class being defined. This setting achieves the same result as explicitly setting the application folder’s urn:schemas-microsoft-com:exch-data:expected-content-class property to the desired list of content classes. This technique is a shortcut rather than later specifying multiple expected content classes for a folder. To have content classes appear in the list of available content classes in Explorer, the folders containing the content class definitions must be included in the schema folder’s urn:schemas-microsoft-com:exch-data:baseschema property.
Extends | Use this tab to list one or more content classes that should be extended in the content class being defined. A typical use of extension is extending the urn:content-classes:person content class. This content class contains a comprehensive set of contact properties, such as homephone and email1. The new content class inherits these properties and custom contact properties can be added. To have content classes appear in the list of available content classes in Explorer, the folders containing the content class definitions must be included in the schema folder’s urn:schemas-microsoft-com:exch-data:baseschema property. You can also enter a content class not listed. Type the content class in the text box below the list of available content classes and click Add ECC.
Advanced | Use this tab to set values for following properties: ComProgID Contains the Prog ID for an object, such as an ActiveX control, for handling items of the content class being defined. Full name: urn:schemas-microsoft-com:comprogid. ComClassID Contains the Class ID for an object, such as an ActiveX control, for handling items of the content class being defined. Full name: urn:schemas-microsoft-com:comclassid. Version You can use this setting for your own versioning scheme for this content class definition. Close Expected Content Classes If checked, the expected content classes listed in this content class definition cannot be extended. This setting is not enforced by the Web Storage System, but an application can use this setting to provide the enforcement.
Note The content class for a content class definition item itself is required to be urn:content-classes:contentclassdef, which is set automatically by the Explorer.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Creating Definitions for Other Schema

Create the schema for AppB in the AppB schema folder. Create one or more property definitions, create the urn:content-classes:microsoft-com:sample2 content class, and add the property definitions to that content class.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Setting Schema Scope

Schema scope is the ability for a search engine or application to find content class and property definitions by following a designated trail of folders. This scope is controlled by four properties that you can edit using the Explorer.

To set schema scope

  • In Schema Detail View, right-click the properties described in the following table, click Edit, and follow the tutorial steps.
Property | Description | Tutorial Step
contentclass | This single-valued property sets the content class for a folder or item. In Explorer, you can set the content class for a folder. | Set the AppA folder's content class to urn:content-classes:microsoft-com:sample1, and the AppB folder's content class to urn:content-classes:microsoft-com:sample2.
schema-collection-ref

This single-valued property, set on application folders, specifies the URL that points to the first folder that contains applicable schema definition items.

The schema scope for any folder always starts with a single folder in the store. You can further expand the scope by setting the urn:schemas-microsoft-com:exch-data:baseschema field on the first and subsequent schema folders.

 Set this property on the AppA and AppB folders to URLs of their respective schema folders.
baseschema

This multivalued property, set on schema folders, specifies the URLs for folders that contain additional, or base, schema definition items. When an application constructs the list of folders that are in a particular folder's schema scope, each folder identified by this property is added to the list in the order in which it appears in this field.

Note that, by convention, you set this property for designated application schema folders and not for the application folder itself.

The order in which folders are searched is significant: if two or more property definition items exist that have the same value for urn:schemas-microsoft-com:xml-data#name, only the first definition is used.

To obtain the global schema definitions, add the non_ipm_subtree/schema folder to this property's values, such as http://Server1/public/non_ipm_subtree/Schema. The global schema URL does not appear in the URL selector, but you can type it in the text box.

 Set this property on AppA's schema folder to contain the URL to AppB's schema folder.
expected-content-class

The expected-content-class property is an array (list) of content class names that are designated as expected for items in the folder. This property does not itself define these content classes and does not define in what folder or folders the associated content class and property definition items are kept. Applications search for these definitions within the folder's schema scope. Additionally, the expected-content-class property does not impose a restriction on what the value of an item's content class can be; it simply designates the list of names as expected for items within the folder.

One example use of the expected-content-class property is controlling which properties are returned for items when you execute a SELECT * command on a folder: only the combination of properties defined by all of the expected content classes are returned for each item in the resulting OLE DB Rowset or ADO Recordset.

The expected-content-class, schema-collection-ref and baseschema properties are used together to define a folder's schema. Folders can contain separate content class and property definitions specific to a particular application.

 Set set this property on the AppA folder to contain the urn:content-classes:microsoft-com:sample1 and urn:content-classes:microsoft-com:sample2 content classes.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Testing the Schema

You can use the Explorer to list all properties attributed to a folder.

To test your schema

  • Right-click the AppA folder and click Properties.

    This action lists all the properties on the folder, and is the same as enumerating the Fields collection of an Microsoft® ActiveX® Data Objects (ADO) Record object of the folder.

The list should include all the properties you defined for the urn:content-classes:microsoft-com:sample1 and the urn:content-classes:microsoft-com:sample2 content classes.

To get an understanding of schema scope, examine AppA's properties after you experiment with the following settings:

  • Change AppA's content class back to urn:content-classes:folder. The properties you defined are still available because the schema scope is not affected. The are two reasons to set the application folder's content class:
    • Applications can perform appropriate actions based on the content class, such as displaying contact icons for a contacts folder.
    • The application folder will have properties belonging to the expected-content-classes defined as part of that content class’s definition.
  • Clear the schema-collection-ref property. The properties you defined will be gone because there is no reference to schema locations. Then change it back.
  • Remove the URL from the AppA's schema folder's baseschema property. AppA's properties will only have the properties defined for the urn:content-classes:microsoft-com:sample1 content class because the schema scope stops at AppA's schema folder. Then change it back.
  • Change AppA's expected content class to only have the urn:content-classes:microsoft-com:sample1 content class. You won't see urn:content-classes:microsoft-com:sample2’s properties. Then change it back.
  • Remove both content classes from AppA's expected content classes, and then edit the content class definition for urn:content-classes:microsoft-com:sample1 to include those content classes as its expected-content-classes. Then set AppA's content class to urn:content-classes:microsoft-com:sample1. AppA's properties should list all properties you defined in the tutorial.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Using the Property Viewer

The property viewer, in the Web Storage System Explorer's lower-right pane, displays property values of selected folders and items. Right-click a property for edit features.

Viewing Property Values

When viewing properties and their values, consider the following:

  • The list of properties varies depending on the item or folder's schema scope.
  • Some built-in properties, such as those from the DAV: namespace like DAV:href, cannot be deleted or edited.
  • The Add Property selection on the right-click menu appends a field to that item's, or folder's, Fields collection. This is not the same as creating a property definition item as described in the schema tutorial. In this case the property is only appended to the item; it is not propagated to content classes and is accessible only as long as the item exists. While limiting for some applications, this feature is useful for attributing a value to an item on a casual basis.
  • To avoid scrolling through the list to find a particular property, right-click the property viewer and click Get Named Property to look up that property.
  • Avoid editing property names. A changed name of a property does not result in a change to that property, but a new property with that name.
  • Properties that contain URL values, such as urn:schemas-microsoft-com:exch-data:schema-collection-ref, are calculated and UTF-8 encoded. They contain escape characters such as %20. By using the Web Storage System Explorer, you can select folders and items and avoid the complexity of entering these characters.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Creating Web Storage System Form Registrations

You can use the Web Storage System Explorer to create form registrations.

To Create a Form Registration

  1. On the File menu, click Add Form Registration.
  2. Enter a name for the form registration and click Next.
  3. Enter the URL of the form and click Next.
  4. From a drop-down list, enter or select an action that your form performs and click Next.
  5. From a drop-down list, select which browsers your form supports and click Next. Select Any for all browsers.
  6. Select the data binding type: Client, Server, or WebClient, and click Next.
  7. Select the request method: Any, Post, or Get, and click Next.
  8. Enter or choose a content class and click Next.
  9. Click Finish.

The wizard creates the form registration as a hidden item in the currently selected folder, and also sets the value of the executeURL property.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Creating Web Storage System Event Registrations

You can use the Web Storage System Explorer to create event registrations.

To Create an Event Registration

If you are using a COM object as an event sink, that object must be registered on the server and configured as a COM+ application before creating an event registration.

If you are using a script as an event sink, register Exodbesh.dll (in the \Program Files\Exchsvr\Bin folder) and configure it as a COM+ application before creating an event registration. The class that needs to be registered with COM+ is ExOleDB.ScriptEventSink.

For more information about configuring event sinks in COM+ applications, see the topic Creating a COM+ Event Sink Application for the Event Sink Wizard tool.

Use the following steps to create an event registration.

  1. On the File menu, click Add Event Registration.
  2. Enter a name for the event registration and click Next.
  3. Choose the kind of event to register: Asynchronous, Synchronous, MDB, or Timer, and click Next. For more information about these events, see Event Descriptions, a topic for the Event Sink Wizard tool.
  4. Depending on the event type selected, choose one or more events that are applicable to your registration and click Next. If you selected a Timer event, you can specify the time and frequency for the event to fire.
  5. If you selected asynchronous events, choose a Deep or an Exact scope. If you selected synchronous events, choose an Any, Deep, or Shallow scope. An Any scope is the scope of the MDB. An Exact and Shallow scope both perform a shallow traversal on the folder. A Deep scope recursively traverses subfolders, but is not available on the MAPI public store that is installed by Microsoft® Exchange 2000 Server. In addition to the event's scope, you can specify a WHERE clause to limit the scope to a specified criteria. Then click Next.
  6. Choose whether you are registering a COM event sink or a script, and then click Next.
  7. If you are using a COM object, specify its Prog ID. If you are using a script, enter its path, and then click Next.
  8. Click Finish.

The wizard creates the event registration as a hidden item in the currently selected folder.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Web Storage System Event Sink Wizard

Microsoft Web Storage System events enable you to develop applications that can be triggered by events (such as when an item is saved or deleted), as well as being triggered by timer and system events.

The Web Storage System Event Sink Wizard for Microsoft® Visual Basic® creates a Visual Basic project of commented code for creating a Microsoft® ActiveX® Control DLL as your event sink.

This section consists of the following topics:

Introduction to the Event Sink Wizard

Setting Up the Event Sink Wizard

Using the Event Sink Wizard

Related Topics

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Introduction to the Event Sink Wizard

Microsoft Web Storage System events enable you to develop applications that can be triggered by events, such as when an item is saved or deleted, as well as responding to timer and system events.

This wizard creates a Microsoft® Visual Basic® project for a COM class of correctly implemented event interfaces, and a module of functions and routines that utilize event sink support interfaces.

To provide a security context for your event sink to run out-of-process on Microsoft® Exchange 2000 Server, you must wrap your event sink as a COM+ component application. You then register your event sink using a supplied Visual Basic script, Regevent.vbs.

This section documents all these procedures. The first step is to set up the Event Sink Wizard.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Setting Up the Event Sink Wizard

The Web Storage System Tools installation installs the Event Sink Wizard as an add-in component for Microsoft® Visual Basic® applications. You need to use the Add-In Manager to make the Event Sink Wizard available on the Visual Basic Add-Ins menu.

To load the Event Sink Wizard Add-In

  1. From the Add-Ins menu in Visual Basic, click Add-In Manager.
  2. In the Available Add-Ins list, select Web Storage System VB Event Sink Wizard.
  3. In the Load Behavior settings, verify that the Loaded/Unloaded check box is checked.
  4. Click OK to close.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Using the Event Sink Wizard

Use this procedure whenever you want to create an event sink DLL for handling Web Storage System events.

To Run the Event Sink Wizard

  1. From the Add-Ins menu, click Web Storage System VB Event Sink Wizard.
  2. Click Next.
  3. In the wizard's Selection of Events dialog box, check the events that you want to trap. You can choose Synchronous Events, Asynchronous Events, or System Events.

    For more information about these events, see Event Descriptions.

  4. Click Next.
  5. In the wizard's Selection of Options dialog box, specify one or more of the following code creation options:
    • Insert file logging code into each event.

      Creates the routine to log event sink status information to a text file on the server. You can modify the logged information, text file name, and location.

    Note You can increase the performance of your event sink DLL by disabling this routine after debugging or when status information is no longer needed. You can also set the PERFORM_FILE_LOGGING constant to False in the project's code module.
    • Insert a breakpoint into each event.

      You can run your event sink in the Microsoft® Visual Basic® debug mode. Select this option to insert to breakpoints into each event. Breakpoints are ignored when the project is compiled.

    • All public registration of the event

      Implements the ICreateRegistration interface so that you can trap event registration events, providing the opportunity to perform checks and prevent the event from being registered.

  6. Click Next and then click Finish.

You can now modify the project with your code.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Modifying the Visual Basic Project

The Microsoft Web Storage System Event Sink Wizard creates a new Microsoft® Visual Basic® project according to the options you specify. The project created is highly commented and indicates where to insert your code. The project also contains commented functions and subroutines that you may want to uncomment so they can be implemented.

The following table is guide to where to modify event-handling code. Synchronous events are called twice, once in the beginning and again after a commit or rollback, enabling you to include checking and error-handling code in its routines.

Events | Project location | Routines and functions to modify
Asynchronous | Class | IExStoreAsyncEvents_OnDelete, IExStoreAsyncEvents_OnSave
Synchronous | Module | ProcessBeginSave, ProcessCommitSave, ProcessAbortSave, ProcessBeginDelete, ProcessCommitDelete, ProcessAbortDelete
System | Class | IExStoreSystemEvents_OnMDBShutDown, IExStoreSystemEvents_OnMDBStartUp, IExStoreSystemEvents_OnTimer

After you have modified the code and made the Microsoft® ActiveX® DLL, you need to create a COM+ application for the event sink.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Creating a COM+ Event Sink Application

To provide a security context so that your event sink can run out-of-process on Microsoft® Exchange 2000 Server, you must wrap your event sink as a COM+ component application.

To create a COM+ application for an event sink

  1. Click Start, point to Programs, then Administrative Tools, and click Component Services.
  2. In Component Services, select COM+ Applications under Console Root\Component Services\My Computer.
  3. Right-click COM+ Applications, point to New, and click Application.
  4. Click Next, then click Create an empty application.
  5. Name the application; verify that Server application is checked, and then click Next.
  6. Click Next and then Finish.
  7. Open the new application, and right-click Components in the tree view.
  8. Click New and then click Component.
  9. Click Import component(s) that are already registered.
  10. When the list displays, select your project such as project1.class1.
  11. Click Finish, and then OK to close Component Services.

Now you’re ready to register the event sink.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Registering an Event Sink

After you have created your event sink, you need to register it with the Microsoft Web Storage System.

To register an event sink

  1. Determine the folder where you want to place the event sink, such as file://./backofficestorage/sampledom.microsoft.com/public folders/test.
  2. Using Regevent.vbs, register the event at a command prompt shown as follows:
cscript regevent.vbs add|delete|enum eventmethod sinkclass itemname starttime(interval) interval(interval)

Example

cscript regevent.vbs add "onsyncsave;onsyncdelete" project1.class1 "file://./backofficestorage/sampledom.microsoft.com/vbsink/sink1".

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Event Descriptions

This section describes basic information about synchronous, asynchronous, and system events.

Synchronous Events

Synchronous events are called twice, once in the begin phase and again while the transaction is being committed or aborted. The IExStoreSyncEvents Interface has two methods, as described in the following table.

Event | Description
IExStoreSyncEvents::OnSyncSave | Called when an item is saved to the Microsoft Web Storage System, but before the changes are committed.
IExStoreSyncEvents::OnSyncDelete | Called when an item is deleted from the Web Storage System, but before the delete is committed.

Note Moving an item triggers both the OnSyncDelete and OnSyncSave events.

Asynchronous Events

Asynchronous events occur after the item is committed to the store. The IExStoreAsyncEvents Interface has two methods, as shown in the following table.

Event | Description
IExStoreAsyncEvents::OnSave | Called when an item is saved to the store after the changes are committed.
IExStoreAsyncEvents::OnDelete | Called when an item is deleted from the store after the delete is committed.

Note Moving an item triggers both the OnDelete and OnSave events.

System Events

IExStoreSystemEvents Interface has three methods, as described in the following table.

Event | Description
IExStoreSystemEvents::OnTimer | Called after a specified period of time.
IExStoreSystemEvents::OnMDBStartUp | Called when the Web Storage System MDB is started.
IExStoreSystemEvents::OnMDBShutDown | Called when the Web Storage System MDB is shut down.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Web Storage System Workflow Configuration Scripts

The Web Storage System workflow setup scripts do the following:

  • Wfsetup.vbs configures the server for correct workflow functionality.
  • Addwfrole.vbs adds users to workflow event sink security roles.

The Web Storage System tools installation program installs these scripts in the \Program Files\Web Storage System\Tools\Workflowsetup directory. These scripts must be run on Microsoft® Exchange 2000 Server that is also a Domain Controller.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Wfsetup.vbs

Wfsetup.vbs performs the one-time server configuration steps required before you can install and run workflow applications on your server. This time-saving script eliminates troubleshooting caused by improper configurations.

Usage

Enter the following command at a command prompt:
cscript wfsetup.vbs username password

username | Name of an existing Microsoft® Windows® 2000 domain account in the form domain\account. The workflow event sink executes with this identity.
password | Password for the preceding account.

Remarks

Do not run wfsetup.vbs on a machine with active workflow folders. Wfsetup.vbs shuts down the workflow event sink thus aborting any workflows in process.

This script performs the following actions:

  • Adds the account to the Microsoft® Exchange Domain Servers group for your current domain. This step can fail if there are lengthy Microsoft® Active Directory® replication delays.
  • Adds the account to the Privileged Workflow Authors role.
  • Verifies the account has an Exchange mailbox. If the account does not have a mailbox, you will not be able to run mail-based workflows. Mail-based workflows are workflows that use the content of e-mail messages to advance a workflow item.
  • Sets the "Maximum execution time for scripts in seconds" registry key to 900 seconds. This registry setting facilitates testing of workflow scripts by giving you more time to debug a running script.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Addwfrole.vbs

This Microsoft® Visual Basic® Scripting Edition (VBScript) script adds a user to one or both Workflow Event Sink security roles.

Usage

cscript addwfrole.vbs username -p
username | Username of an existing Microsoft® Windows® 2000 domain account.
-p | Optional. Adds the user to the "Privileged Workflow Authors" role.

Remarks

This script performs the following actions:

  • Adds username to the "Can Register Workflow" Workflow Event Sink security role. This role allows a user to develop typical Workflow applications with restricted ability to create server objects.
  • Optionally, the -p switch adds a username to the "Privileged Workflow Authors" Workflow Event Sink security role. This role allows a user to develop workflow applications with no restriction on creating server objects.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Web Storage System Application Deployment Wizard

You can use the Web Storage System Application Deployment Wizard to both package Web Storage System applications and to deploy applications on the Web Storage System. You can use this wizard on a Microsoft® Exchange 2000 Server computer and with the Microsoft Pre-release Product (code-named "Tahoe"), but not within the Tahoe workspace.

You can also pack and deploy applications programmatically. For information about using this API, see Packaging and Deployment in the Reference section.

This section consists of the following topics:

Introduction to the Web Storage System Application Deployment Wizard

Setting Up the Web Storage System Application Deployment Wizard

Using the Web Storage System Application Deployment Wizard

Related Topics

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Introduction to the Web Storage System Application Deployment Wizard

The Web Storage System Application Deployment Wizard performs two functions: packaging applications and deploying them. The following figure shows the wizard's first screen:

The wizard begins by presenting these two options:

Package Application

Use this option to package an existing Web Storage System application for later deployment. You have two options for packaging applications:

  • Package the application as a CAB file.
  • Package the application as a folder of its contents.

Both packaging options create the package in the Microsoft® Windows® file system as well as creating an XML manifest file, Package.xml. This manifest file describes the application's items, folders, registrations, and schema definitions for use with the Deploy Application option.

Deploy Application

Use this option to install a packaged application in the Web Storage System. This packaged application is either a CAB file or a folder containing the application's contents. The CAB or folder must have an XML manifest file named Package.xml that adheres to the format as created using the Package Application option.

Preparing to deploy your application from a CAB file is a two-step process. First, you must create an application package that contains just Web Storage System application logic and data. Next, you can optionally create a setup program using the Windows Installer technology.

Your Windows Installer setup program must include the application package that this wizard generates, and any other components that your application needs to execute outside the Web Storage System. When building your setup program, you must include the Web Storage System deployment custom action along with your application package. When the setup program calls the custom action, the custom action deploys the Web Storage System application and data into the location specified.

Note If you create an event sink registration for a scripting event sink with the script contained in the event registration, the application deployment wizard will not install the event sink registration correctly. Developers wanting to include event sinks with script should use the Event Wizard as described in Creating Web Storage System Event Registrations.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Setting Up the Web Storage System Application Deployment Wizard

Account for all of your application files.

Confirm Files

To ensure that the wizard operates correctly, the file Cabarc.exe should be in the folder containing any executable files your application contains. This file is installed in the Program Files\Web Storage System\Tools\AppDeployWiz folder.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Using the Web Storage System Application Deployment Wizard

The Application Deployment Wizard accomodates both packaging and deploying applications. The wizard is also useful for archiving and replicating event and form registration items, and schema definition items.

Alternatively, you can pack and deploy applications programmatically. For information on using this API, see Packaging and Deployment in the Reference section.

To run the Application Deployment Wizard

  1. Click Start, point to Programs, point to Web Storage System SDK, point to Web Storage System Tools, and then click Application Deployment Wizard.
  2. Choose Package Application or Deploy Application.
  3. Click Next and follow the wizard's steps.
Note The wizard uses the WebDAV protocol for packaging and deploying applications remotely. This is suitable for packaging and deploying schema or data, but not for large applications containing large binaries. Avoid remotely packaging and deploying applications that are several megabytes in size.

Packaging Applications

The following information is required for packaging applications:

  • The URL to the existing Web Storage System application. You can optionally specify to include subfolders.
  • Username and password. If the username fails to resolve, precede the username with the domain name and a backslash, for example, DomainName\Administrator.
  • The location on your Microsoft® Windows® file system to save the application package. This can either be the path and name for a CAB file, or the path to a folder to contain the application's contents.
  • A schema file to include or exclude properties and to fix items with the correct URLs. The default file, \Program Files\Web Storage System\Tools\AppDeployWiz\samplefilter.xml, excludes such properties as DAV:parentname that would have no relevance in packaging an application.

Deploying Applications

The following information is required for deploying an application in the Web Storage System:

  • The Web Storage System URL of the location where you want to install the application. The wizard creates parent folders if they do not exist.
    Note If you specify a root folder of a top level hierarchy, such http://server1/public, an error dialog box displays confirming that you want to delete the folder. This error shouldn't occur because you cannot delete or install in a root folder. Click No and specify a URL that is not to a root folder.
  • Username and password. If the username fails to resolve, precede the username with the domain name and a backslash, for example, DomainName\Administrator.
  • The location on your Microsoft® Windows® file system of the application to install. This can either be the path and name for a CAB file, or the path to a content folder.

    If the CAB file is on another server, you can specify its URL such as such as http://myserver/public/myfolder/myapp.cab.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Packaging a Windows Setup Program

After you have created your application package, you need to develop a Microsoft® Windows® install setup program. Windows Installer is an installation and configuration service that ships as part of the Windows 2000 operating system, and is provided through a service pack to users of Windows 95, Windows 98, and Microsoft® Windows NT®.

For complete information about the Windows Installer, go to http://msdn.microsoft.com/library/default.asp?URL=/library/psdk/msi/wiport_6gf9.htm.

In addition, there are third-party tools that enable you to build setup programs that use the Windows Installer.

  • http://www.installshield.com
  • http://www.wisesolutions.com
  • http://www.installshield.com

The target variables to use in the setup program are as shown in the following table.

Target variable | Description
Exapppackagefilepath | The Web Storage System Application package path. This points to the package file in Step 1.
Exapptargeturl | The target URL. This is typically user supplied and contains the URL of the server where the application is to be installed.
Exappusername | Accessing the Web Storage System requires authentication. Both the user name and the password are required.
Exapppassword | Password.

To build your setup program

  1. Add Cabarc.exe, which is installed in the Program Files\Web Storage System\Tools\AppDeployWiz folder, and the application package to your setup file list.
  2. Create the following custom actions:

    SetCAData - Sets the property, ExInstaller, to be used by the ExInstaller custom action. This property specifies properties required during installation. This call must be made before calling ExInstaller.

    Type | Source | Target Variables | Example
    51 | Entry ID in binary table of ExInstaller.DLL | ExAppPackageFilePath, ExAppTargetURL, ExAppUserName, ExAppPassword The user can supply each of these variables. This requires a new dialog to be created. | New_Binary1

    ExInstaller - Installs files from application package to target server. This custom action should not be called during remove, so Condition = not Remove.

    Type | Source | Target Variables | Example
    1025 | Entry ID in binary table of ExInstaller.DLL. | ExInstCustomAction | New_Binary1

    ExSchedule - Initializes the progress bar. Placing ExSchedule immediately after the standard action ProcessComponents is recommended. This custom action should not be called during remove, so Condition = Not Remove.

    Type | Source | Target Variables | Example
    1 | Entry ID in binary table of ExInstaller.DLL | ExInstCustomAction | New_Binary1
  3. Create a custom dialog box to collect the three parameters Exapptargeturl, exappusername, and exapppassword.
  4. After the custom actions have been defined, you need to schedule the custom actions in a sequence table.

Sample.ism

Sample.ism is a sample InstallShield for Windows Installer project file that shows how to integrate the installation custom action with Windows Installer technology. This file is installed in the Program Files\Web Storage System\Tools\AppDeployWiz folder. In that folder is Ism_readme.txt that describes how to create an .msi file.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Schema Filters for Packaging

A schema filter is used to explicitly include or exclude properties in your application. This will speed up the setup process that follows. You may also specify properties that use absolute URLs and how they should be fixed.

The following is a list of general rules that the packaging wizard follows when a schema filter is specified:

  • Copy list overrules exclude list.
  • A property is copied if it is not on either list.
  • Use URLNeedFix to specify URL properties that need to be fixed.

You should review package.xml in the cab file after packaging. If there are properties you should exclude, such as GUIDs or read-only properties, you need to modify the schema filter file accordingly and re-run the wizard until you are satisfied with the resulting package.xml.

sampleFilter.xml

A sample schema filter file, sampleFilter.xml, is provided in the Program Files\Web Storage System\Tools\AppDeployWiz folder. You can use this file for your own application packaging with minimal modifications.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Application Security Module

This section describes the Web Storage System Application Security Module.

This section consists of the following topics:

Introduction

Setup

File Descriptions

Supported Configurations

Configuration Scenarios

Sample Application

Programming Tasks

Related Topics

  • Application Security Module Reference
  • Web Storage System Security

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Introduction

The Web Storage System supports Microsoft® Windows® 2000 and Microsoft® Windows NT® security descriptors. Each item and folder has a security descriptor property. This property, along with others in the http://schemas.microsoft.com/exchange/security/ namespace, is stored in a binary format, but is provided as XML.

Note Because architecturally a folder is an item that is also a collection, this documentation uses "item" to refer to either a Web Storage System folder or item.

You can use the Application Security Module, a set of JavaScript and Active Server Pages (ASP) files, to access and modify the XML content provided by the security descriptor. A security descriptor consists of Access Control Entries (ACEs) that specify security identifiers (SIDs) for security principals such as users, administrators, and groups in the Microsoft® Active Directory™. These ACEs are contained in an Access Control List (ACL).

The Application Security Module provides two objects: a DACL (Discretionary Access Control List) object and an entity object. The DACL object can contain one or more entity objects. Entity objects define security principals and their SIDs. In the Security Module, hexidecimal bitmasks identify a user's permissions that are evaluated against an item's SID. To understand how bitmasks are evaluated, see the HasMask Method. The Application Security Module does not provide an object for accessing a SACL (System Access Control List).

To secure an item, create a DACL object and load the item's URL to obtain its DACL. The DACL object contains a collection of entity objects of the existing security principals. You can add and remove entity objects and manipulate the permissions for the secured item.

The Application Security Module uses Microsoft® ActiveX® Data Objects (ADO) on the server to load and save DACL objects, based on input recieved from client browsers. If the browser is Microsoft® Internet Explorer, the client can use an XMLHTTP object to manipulate security descriptors remotely.

This module is supplemented with a sample application that uses the methods and properties defined by core Application Security Module files. You can use this sample with Internet Explorer or any browser that supports JavaScript. You can modify this application and use its code in other applications and scripts.

You can do the following tasks with the Application Security Module:

  • Manage masks on entity objects using methods that compare, copy, and clear masks.
  • Manage entities in DACL objects as a collection, and use the DACL object as a template to manage and compare entities.

The following figure shows the Web Storage System Application Security Module architecture:

Note The Application Security Module does not allow setting permissions on inherited ACEs.

Related Topics

  • Application Security Module Reference
  • Web Storage System Security

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Setup

Install the Application Security Module from the MSDN® Exchange Developer Center Web site at http://msdn.microsoft.com/exchange.

To install the Application Security Module:

  1. Run the setup program on the Web, which installs Securitymodule.exe on your computer.
  2. Run SecurityModule.exe to extract the files to the folder of your choice.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


File Descriptions

The Web Storage System Application Security Module is composed of JavaScript files as described in the following table.

Filename | Description
Security.js | Defines the properties and methods for the DACL and entity objects.
LoadSaveDacl.js | Defines methods for loading and saving an item's XML security descriptor.
CustomLoadSaveDacl.js | Defines methods for loading and saving an item's XML security descriptor for use with browser other than Microsoft® Internet Explorer.
Daclstrutil.js | Contains functions to convert a DACL object to XML strings and back to programmatic elements for use with browsers other than Internet Explorer.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Supported Configurations

The Application Security Module supports two main configurations. The logic for these configuations is controlled by the nLocation parameter in the CreateSecurityDACL Method method, which either sets the security on the server or on the client.

Security on Server

This default configuration uses Microsoft® ActiveX® Data Objects (ADO) on the server to save and load DACL objects. This configuration supports all clients using a browser that supports JavaScript, including Netscape Navigator.

LoadSaveDACL.js has ADO code for loading and saving DACL objects when security is set on the server. This file also has code for instantiating a client XMLHTTP object when security is set on the client.

To support browsers other than Microsoft® Internet Explorer, you must use CustomLoadSaveDacl.js instead of LoadSaveDacl.js. This custom script uses FORM posts and ADO to load and save DACL objects and does not contain any code that instantiates client objects, unlike LoadSaveDacl.js.

The following figure depicts a Security on Server configuration in which ADO is used to load and manipulate the XML of the security descriptor as DACL objects. Security.js contains the Application Security Module's core functions.

Security on Client

This configuration uses LoadSaveDACL.js to instantiate a client XMLHTTP object to remotely update the security descriptor. Only Internet Explorer supports this configuration.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Configuration Scenarios

You can design your application to accommodate the following scenarios:

  • Use the Security on Client configuration so Microsoft® Internet Explorer clients can use XMLHTTP for modifying security descriptors.
  • Use the Security on Server configuration so security descriptors are modifed only by Microsoft® ActiveX® Data Objects (ADO) objects on the server.
  • Set the configuration according to your own business logic or requirements.
  • Set the configuration according to the browser, and accommodate browsers that do not create ActiveX objects such as Netscape Navigator. This scenario, used by the Application Security Module sample application, accommodates all browsers that support JavaScript.

The following figure depicts the program flow for the Application Security Module sample application.

Detecting the Browser

You can use the Active Server Pages (ASP) server variable "HTTP_USER_AGENT" to determine a browser's type. The DACLEditFrame.asp file contains the code that implements this logic.

Implementing Client XMLHTTP Usage

If the browser is Internet Explorer, include LoadEditDacl.js in your application so the browser can use XMLHTTP to remotely manipulate a DACL object. Create the DACL object with security set on the client.

The following ASP code snippet shows how this configuration is implemented.

<script language="javascript"  runat=server  src="loadsavedacl.js"></script>
<script language="javascript"  runat=server  src="security.js"></script>
<Script language="javascript" runat=client src="addusrs.js"> </script>
<%
//Create DACL object with Security on Client
var objDacl = CreateSecurityDACL(SECURITY_ON_CLIENT());
objDacl.Load("http://server/folder");
%>

Accommodating Other Browsers

If the browser is not Internet Explorer, include the CustomLoadEditDacl.js file so that inputs for ADO operations on the server are retrieved from FORM posts and no client objects are created. Create the DACL object with security set on the server.

The following ASP code snippet shows how this configuration is implemented.

<Script language="javascript" src="customLoadSaveDACL.js"> </script>
<Script language="javascript" src="security.js"> </script>
<Script language="javascript" src="daclstrutil.js"> </script>
<Script language="javascript" src="addusrs.js"> </script>
<%
// Create DACL object with Security on Server
var objDacl = CreateSecurityDACL(SECURITY_ON_SERVER());
objDacl.Load("http://server/folder");
%>

The DACLEditFrame.asp file of the Sample Application implements this logic. When customLoadSaveDACL.js is called, browsers that are not Internet Explorer manipulate the DACL object by posting values through hidden form elements and call CustomSaveDACL.asp to save the DACL. The daclstrutil.js file contains routines to parse the text in these form elements in order to create DACL objects and to extract DACL object values.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Sample Application

The sample application provided with the Application Security Module demonstrates the following functionality:

  • Entering an item's URL from which to load that item's security descriptor.
  • Displaying access rights.
  • Modifying access rights.
  • Adding and removing users and groups.

You can reuse its code or modify the application files for your own purposes.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Setup

You can setup the sample application in a virtual directory inside or outside the Web Storage System.

To install the sample application

  • Create a folder for the application.
  • Copy all the files that you extracted from SecurityModule.exe into that folder.
  • In your browser, navigate to the Start.asp file in the public folder containing the Application Security Module, such as http://myserver/public/security/securitymodule/start.asp.
  • Follow the steps as displayed to create the Application Security Module sample application according to your preferences.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


File Descriptions

The Application Security Module sample application is composed of JavaScript and Active Server Pages (ASP) files as described in the following table.

Filename | Description
Start.asp | Creates the sample application according to user preferences.
DaclEditBox.asp | Creates the window and generates the frame layout.
DaclEditBtn.js | Creates the browser window.
DaclEditFrame.asp | Creates the frame at the top of window that holds the list of users.
DaclEditFrame.js | Code for DaclEditFrame.asp.
ADFind.asp | Searches the Active Directory using the inputs in the Add User page.
AddUsrs.js | Creates the window for the browser and generates the frame layout for the Add User page.
AddUsrsFrame.asp | Contains text inputs for the Add User page.
AddUsrsFrame.js | Code for AddUsrsFrame.asp
AddBtns.asp | Creates buttons for the Add User page.
Group.asp | Finds group members.
Blank.htm | Empty file.
btns.htm | Contains HTML for buttons.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Overview

The sample application demonstrates the functionality of the Application Security Module.

The following figure shows the start.asp page of the Application Security Module sample application:

To view rights for a specific item:

  1. Type the item's URL in the URL text box.
  2. Select desired display options, or click Show Default Selections for commonly displayed options.
  3. Click Go to display security settings.
Note You can use this application on secured servers using https, however you will get an access denied error if you load the application using https but attempt to view an item's security settings by entering its http URL in the URL text box. Do not mix https and http URLs when using this application.

To modify users and groups and their rights:

The following figure shows the settings.asp page of the Application Security Module sample application:

  1. In the Security Settings dialog box, select a user or group in the displayed list. The rights for the selected user or group display in the permissions frame, the bottom half of the dialog box. If you want to show an advanced list of permissions, click Show Advanced.
  2. Check the rights to be granted to the user or group, or uncheck the rights that you want to deny. Instead of setting individual rights, you can apply the user or group to a role by selecting from a list of predefined legacy roles.
  3. Click Apply to save the settings. If you want to view the rights for another item, type the URL in the URL text box and click Go.
  4. If you want to add a user or group, click Add user/group. A dialog box displays for searching and adding users and groups. You can only add groups if they have e-mail addresses.
  5. If you want to remove a user or group, click Remove. A message displays asking you to confirm the removal.
  6. Click OK or Apply.
Note The Application Security Module does not allow setting permissions on items that have inherited ACEs. Consequently, if the URL you provided references an item that only has inherited permissions, then you will not be able to modify any of the existing users or groups, but you can add new users or groups.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Programming Tasks

This section contains programming tasks performed by the Web Storage System Application Security Module sample application.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Retrieve and Save XML Security Descriptor

RetrieveSave.asp loads and saves a DACL object.

<%
// This sample shows how to retrieve an XML Security Descriptor and to save it back on the item.
function RetrieveSave(itemURL)
{
    var objDacl = CreateSecurityDACL(SECURITY_ON_SERVER());

    // Load the security descriptor in dacl object.
    var objLoadResult = objDacl.Load(itemURL);
    if (objLoadResult.number != 0)
    {
          Response.Write("<b>Failed to Load: " + objLoadResult.description + "</b><br>");
        return(objLoadResult.number);   //error loading the object ...maybe the url does not exist....
    }

     //Display some properties of the DACL
    Response.Write("Location of the Item: "+ objDacl.Loc + "<br>");
    Response.Write("URL of the Item: " + objDacl.URL + "<br>");
    Response.Write("Total Entities: " + objDacl.Count + "<br>");
    if ( objDacl.Count > 0 ) //If there are any users, show the first one
    {
          var entityUser = objDacl.Entities[0];
          Response.Write("Display Name of First Entity: " + entityUser.DisplayName + "<br>");
     }

     //Save the DACL object
    var objResult = objDacl.Save();
    if (objResult.number != 0)
    {
        Response.Write("<b>Failed to Save DACL: " +objResult.number + " "+ objResult.description + "</b><br>");
       return(objResult.number);  //Maybe not enough permissions to write the xml property
    }
    return(0); //no error
}
%>

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Copying Rights from URLs

Copyrightsfromurl1tourl2.asp extracts the rights that a user has on a certain URL and adds the same rights for that user to another URL.

<%
//  This sample creates a user named "User2" on ITEM2 that has same rights as "User2" on ITEM2.
function CopyRightsFromURL1ToURL2(NT4user, itemURL1, itemURL2)
{
    var objDacl1 = CreateSecurityDACL(SECURITY_ON_SERVER());
    var objDacl2 = CreateSecurityDACL(SECURITY_ON_SERVER());

    // Load the 2 dacl from the 2 items.
    var objLoadDacl1Result = objDacl1.Load(itemURL1);
    if (objLoadDacl1Result.number != 0)
    {
          Response.Write("<b>Failed to Load: " + objLoadDacl1Result.description + "</b><br>");
        //error loading the object ...maybe the url does not exist....
        Return(objLoadDacl1Result.number);
    }

    var objLoadDacl2Result = objDacl2.Load(itemURL2);
    if (objLoadDacl2Result.number != 0)
    {
          Response.Write("<b>Failed to Load: " + objLoadDacl2Result.description + "</b><br>");
        //error loading the object ...maybe the url does not exist....
        return(objLoadDacl2Result.number);
    }

    //get the 2 users
    var entityUser1 = objDacl1.SearchForObjectByNT4Name(NT4user);
    if (null == entityUser1)
    {
          Response.Write("<b>Failed to Search for object by display name</b><br>");
        return(-1);   //maybe the user does not exist......
    }

    var objResult = objDacl2.AddSimpleSecurityEntity(NT4user,entityUser1.Masks);
    //we use the function here because the user may be in the dacl already
    //add returns a 1 if the user is in the dacl already
    if(FAILED(objResult.number))
    {
       Response.Write("<b>Failed to AddSimpleSecurityEntity</b><br>");
      return(objResult.number);
    }

    objResult = objDacl2.Save();
    if (objResult.number != 0)
    {
        Response.Write("<b>Failed to Save DACL: " + objResult.description + "</b><br>");
       return(objResult.number);
    }

 return(0); //no errors
}
%>

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Copying User Masks

Copyusermasks.asp grants a user in the Microsoft® Active Directory™ rights on an item. These rights are copied from the rights that another user has on the same item.

<%
// This sample shows how to add a user (User2) that mask is a copy of a different users (User1) on same item.
function CopyUserMasks(user1, user2, itemURL)
{
    var objDacl = CreateSecurityDACL(SECURITY_ON_SERVER());

    // Load the security to dacl.
    var objLoadResult = objDacl.Load(itemURL);
    if (objLoadResult.number != 0)
    {
          Response.Write("<b>Failed to Load: " + objLoadResult.description + "</b><br>");
        return(objLoadResult.number);   //error loading the object ...maybe the url does not exist....
    }

    var objResult = objDacl.CopyUserMasks(user1, user2);
    if (objResult.number != 0)
    {
        Response.Write("<b>Failed to Copy UserMasks: " +objResult.number + " "+ objResult.description + "</b><br>");
       return(objResult.number);
    }

    objResult = objDacl.Save();
    if (objResult.number != 0)
    {
        Response.Write("<b>Failed to Save DACL: " +objResult.number + " "+ objResult.description + "</b><br>");
       return(objResult.number);
    }
 return 0;   //no errors
}
%>

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Deleting User Rights

Deleteuserbynt4name.asp deletes an entity from a DACL object by its domain and username (nt4name).

 <%
 // Remove entity User from dacl by nt4namee.
 function DeleteUserByName(user, itemURL)
 {
     var objDacl = CreateSecurityDACL(SECURITY_ON_SERVER());

     // Load the security descriptor in dacl object.
     var objLoadResult = objDacl.Load(itemURL);
     if (objLoadResult.number != 0)
     {
           Response.Write("<b>Failed to Load: " + objLoadResult.description + "</b><br>");
         return(objLoadResult.number);   //error loading the object ...maybe the url does not exist....
     }

     // remove the user
     var objResult = objDacl.RemoveByNT4Name(user);
     if (objResult.number != 0)
     {
         Response.Write("<b>Failed to RemoveByDisplayName: " +objResult.number + " "+ objResult.description + "</b><br>");
        return(objResult.number);
     }

     //Save the DACL on the item
     objResult = objDacl.Save();
     if (objResult.number != 0)
     {
         Response.Write("<b>Failed to Save DACL: " +objResult.number + " "+ objResult.description + "</b><br>");
        return(objResult.number);
     }

   return(0);  //no error
 }
 %>

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Listing User Rights

Listuserrights.asp renders a list of user rights in a table.

<%
// This sample lists all the users, their properties and masks in a DACL object.
function ListUserRights(itemURL)
{
    var objDacl = CreateSecurityDACL(SECURITY_ON_SERVER());

    // Load the security descriptor in dacl object.
    var objLoadResult = objDacl.Load(itemURL);
    if (objLoadResult.number != 0)
    {
          Response.Write("<b>Failed to Load: " + objLoadResult.description + "</b><br>");
        return (objLoadResult.number);   //error loading the object ...maybe the url does not exist....
    }
     ShowSecurityDACL(objDacl); //print the dacl
    return(0);
}

function ShowSecurityEntity(entity)
{
     Response.write ("<td>" + entity.SID + "</td>")
     Response.write ("<td>" + entity.DisplayName + "</td>")
     Response.write ("<td>" + entity.NT4Name + "</td>")
     Response.write ("<td>" + entity.SIDType + "</td>")
     Response.write ("<td>"
                + " " + entity.Masks[0]
                    + " " + entity.Masks[1]
                    + " " + entity.Masks[2]
                    + " " + entity.Masks[3]
                    + " " + entity.Masks[4]
                    + " " + entity.Masks[5]
                    + "</td>")
     Response.write ("<td>" + entity.Inherited + "</td></tr>")
}

function ShowSecurityDACL(dacl)
{
     var i;

     Response.write ("<b>Object.: '" + dacl.URL + "'</b><br>")
     Response.write ("Count: " + dacl.Count + "<br>")
     Response.Write ("<Table border cellspacing=0 cellpadding=5>");
     Response.Write ("<tr><th>Role</th>"
                         +"<th>SID</th>"
                         +"<th>DisplayName</th>"
                         +"<th>NT4Name</th>"
                         +"<th>SIDType</th>"
                         +"<th>Mask</th>"
                         +"<th>Inherited</th></tr>");
     for (i = 0; i < dacl.Count; i++)
     {
          Response.write ("<tr><td>" + i + "</td>")
          ShowSecurityEntity(dacl.Entities[i])
     }
     Response.Write ("</Table>");
}
%>

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Setting Custom Masks

Setcustommasks.asp grants a user rights to access an item using a custom mask.

<%
// Sets custom masks on an existing entity of the DACL
function SetCustomMasks(user, itemURL).
{
    var objDacl = CreateSecurityDACL(SECURITY_ON_SERVER());

    // Load the security descriptor in dacl object.
    var objLoadResult = objDacl.Load(itemURL);
    if (objLoadResult.number != 0)
    {
          Response.Write("<b>Failed to Load: " + objLoadResult.description + "</b><br>");
        return(objLoadResult.number);   //error loading the object ...maybe the url does not exist....
    }

    //Get the entity object on which the masks need to be set
    var entityUser = objDacl.SearchForObjectByDisplayName(user);
    if (null==entityUser)
    {
          Response.Write("<b>Failed to Search for object by display name</b><br>");
       return(-1);   //maybe the user does not exist......
    }

    //Set the Custom Masks
    if(objDacl.isFolder){   //if the item is a folder, then do folder perms
      var daclWSFolderTemplate = DaclWebStorageFolder();  //dacl for Folder rights
      entityUser.SetByTemplate(daclTemplate, "WS Folder Create container");
      entityUser.SetByTemplate(daclTemplate, "WS Folder Write SD");
    }else{
      var daclTemplate = DaclWebStorageItem();   //dacl for Item rights
      entityUser.SetByTemplate(daclTemplate, "WS Read properties");
      entityUser.SetByTemplate(daclTemplate, "WS Write body");
    }

    //Save the DACL on the item
    objResult = objDacl.Save();
    if(objResult.number != 0)
    {
        Response.Write("<b>Failed to Save DACL: " + objResult.description + "</b><br>");
       return(objResult.number);
    }
    return(0);
}
%>

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Setting MAPI Roles

Setlegacymasks.asp grants a user rights to access an item using a legacy mask. This functionality is similar to that of Microsoft® Exchange 5.5.

<%
// This sample shows how to set the permissions for a user, with the predefined legacy role "Author".
function SetLegacyMasks(NT4User, itemURL)
{
    var objDacl = CreateSecurityDACL(SECURITY_ON_SERVER());

    // Load the security descriptor in dacl object.
    var objLoadResult = objDacl.Load(itemURL);
    if (objLoadResult.number != 0)
    {
          Response.Write("<b>Failed to Load: " + objLoadResult.description + "</b><br>");
        return(objLoadResult.number);   //error loading the object ...maybe the url does not exist....
    }

     //Add an empty user entity to the DACL
    var objResult = objDacl.AddEmptySecurityEntity("", "", NT4User, "");
    if (objResult.number != 0)
    {
        Response.Write("<b>Failed to AddEmptySecurityEntity: " +objResult.number + " "+ objResult.description + "</b><br>");
       return(objResult.number);
    }

    // Get the legacy roles DACL template
    var objDLR = DaclLegacyRoles();

    // Set the legacy Role Author on the user just added
    objResult = objDacl.SetByTemplate(NT4User, objDLR, "Author");
    if(objResult.number != 0)
    {
        Response.Write("<b>Failed to Set Template: " +objResult.number + " "+ objResult.description + "</b><br>");
       return(objResult.number);
    }

    //Save the DACL on the item
    objResult = objDacl.Save();
    if(objResult.number != 0)
    {
        Response.Write("<b>Failed to Save DACL: " +objResult.number + " "+ objResult.description + "</b><br>");
       return(objResult.number);
    }

    return(0);  //no error
}
%>

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Application Templates

Visit http://msdn.microsoft.com/downloads/default.asp?URL=/code/sample.asp?url=/msdn-files/027/001/474/msdncompositedoc.xml to download the following Microsoft Web Storage System templates:

  • A Contacts application template that integrates Instant Messaging presence information.
  • A TeamToDo application template that provides basic functionalities and workflow for tasks and issues management.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Reference

The following sections provide information to use when building applications using the Web Storage System.

Developer Resources

Collaboration Data Objects

Web Storage System

Exchange 2000 Instant Messaging Service

Conference Technology Provider

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Developer Resources

This section contains reference information for tools and other resources that are supplemental to the Microsoft Web Storage System SDK.

TreeView Control

atFunction Interfaces

Application Security Module Reference

Packaging and Deployment

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


TreeView Control

This section contains reference information for the TreeView control. See Web Storage System TreeView Control for information on how to program the control.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


EXTV Interface

The TreeView control’s default interface contains, methods and properties that add, remove, and move Web Storage System resources on the Exchange 2000 Server. In addition, the TreeView control’s default interface add and manipulate node hierarchies, get information about a selected node, and specify TreeView control settings.

© 2000-2001 Microsoft Corporation. All rights reserved.


Properties and Methods

This section describes the EXTV interface’s properties and methods for programming the Web Storage System TreeView control.

Note For standard Visual Basic properties, methods, and events, see the Microsoft Visual Basic documentation in the MSDN® Library.


DragOff Property

The DragOff property disables the control’s drag and drop functionality.

[Visual Basic,VBScript]
Property DragOff as Boolean
[C++]
HRESULT get_DragOff(VARIANT_BOOL* pVal);
HRESULT put_DragOff(VARIANT_BOOL pVal);
[IDL]
HRESULT [propget] DragOff([out,retval] VARIANT_BOOL* pVal);
HRESULT [propput] DragOff([in] VARIANT_BOOL pVal);

Remarks

The TreeView control only allows dragging between nodes.

Example

The following example disables dragging and dropping.

[Visual Basic]
EXTV1.DragOff = True
© 2000-2001 Microsoft Corporation. All rights reserved.


Status Property

The Status property provides the status of a WebDAV response.

[Visual Basic,VBScript]
Property Status as String
Read-only.
[C++]
HRESULT get_Status(BSTR* pVal);
[IDL]
HRESULT [propget] Status([out,retval] BSTR* pVal);

Remarks

This property is reserved for future use.


AddRootNode Method

The AddRootNode method adds a node to the TreeView control using a Uniform Resource Locator (URL) to a top-level hierarchy in Web Storage System.

[Visual Basic]
Function AddRootNode(
    ByVal URL as String,
    ByVal displayname As String
    [ByVal expand as Boolean,]
    [ByVal username as String,]
    [ByVal password as String]
)
[C++]
HRESULT AddRootNode(
    BSTR URL,
    BSTR displayname
    [VARIANT_BOOL* expand,]
    [BSTR* username,]
    [BSTR* password]
);
[IDL]
HRESULT AddRootNode(
    [in] BSTR URL,
    [in] BSTR displayname,
    [in, out, optional] VARIANT_BOOL* expand,
    [in, out, optional] BSTR* username,
    [in, out, optional] BSTR* password
);
URL
A URL to a public or private top-level hierarchy in the Web Storage System. The Web Storage System folder must be a virtual directory.

Note Do not UTF-8 encode the URL for this method.

displayname
A display name for a specific node; this name does not correspond to any Web Storage System property.
Expand (optional)
A TRUE value expands any child nodes when the node is selected.
Username (optional)
A username if authentication is required.
Password (optional)
A password if authentication is required.

Remarks

This method is typically used in the Microsoft Visual Basic form load event, so that the control is populated with one or more nodes at run time. Otherwise you add a root node based on a URL that is typed by the user.

Example

The following example adds a root node to the TreeView control.

[Visual Basic]
Dim strURL, strDsp As String
strURL = InputBox("Enter root url:")
strDsp = InputBox("Enter display name:")
EXTV1.AddRootNode strURL, strDsp, True
© 2000-2001 Microsoft Corporation. All rights reserved.


CreateResource Method

The CreateResource method creates a resource as a subfolder in the Web Storage System and adjusts the TreeView control hierarchy to reflect the change.

[Visual Basic]
Function CreateResource(
    ByVal parentURL as String,
    ByVal name As String
)
[C++]
HRESULT CreateResource(
    BSTR parentURL,
    BSTR name
);
[IDL]
HRESULT CreateResource(
    [in] BSTR parentURL,
    [in] BSTR name
);
parentURL
The URL of a folder that contains the new subfolder. This URL must be UTF-encoded or derived from a TNode object.
name
The name of the new folder.

Remarks

This method creates resources in the Web Storage System.

Example

The following example uses a TNode object to get the selected node’s URL, prompts for the name, and creates the folder.

[Visual Basic]
Dim Nd As TNode
Dim strF As String
Set Nd = EXTV1.GetSelectedNode
strF = InputBox("Enter folder name:")
EXTV1.CreateResource Nd.url, strF
© 2000-2001 Microsoft Corporation. All rights reserved.


DeleteResource Method

The DeleteResource method deletes a folder in the Web Storage System and adjusts the TreeView control hierarchy to reflect the change.

[Visual Basic]
Function DeleteResource(
    ByVal URL as String,
)
[C++]
HRESULT DeleteResource(
    BSTR URL,
);
[IDL]
HRESULT DeleteResource(
    [in] BSTR URL,
);
URL
The URL of a folder to delete. This URL must be UTF encoded or derived from a TNode object.

Remarks

This method deletes resources in the Web Storage System.

Example

The following example uses a TNode object to get the selected node’s URL and deletes the folder.

[Visual Basic]
Dim Nd As TNode
Set Nd = EXTV1.GetSelectedNode
EXTV1.DeleteResource Nd.url
© 2000-2001 Microsoft Corporation. All rights reserved.


GetRootNode Method

The GetRootNode method obtains a root node object from a valid root URL.

[Visual Basic]
Function GetRootNode(
    ByVal URL as String,
) As RootNode
[C++]
HRESULT GetRootNode(
    BSTR URL,
    _RootNode**  pVal
);
[IDL]
HRESULT GetRootNode(
    [in] BSTR URL,
    [out, retval] _RootNode**  pVal
);
URL
A valid root URL to a root node. This URL must be UTF encoded or derived from a TNode object.

Remarks

This method does not extract a node from a URL pointing deeper in the hierarchy. The root node must exist in the RootNodes collection.

Example

The following example uses a TNode object to get the selected node’s URL, obtains the root URL, and creates a root node object.

[Visual Basic]
Dim rn As RootNode
Dim tn As TNode
Set tn = EXTV1.GetSelectedNode
Set rn = EXTV1.GetRootNode(tn.RootUrl)
MsgBox rn.url
© 2000-2001 Microsoft Corporation. All rights reserved.


GetRootNodes Method

The GetRootNodes method obtains a collection of root nodes that have been added by the control.

[Visual Basic]
Function GetRootNode() As RootNodes
[C++]
HRESULT GetRootNodes(
    _RootNodes**  pVal
);
[IDL]
HRESULT GetRootNodes(
    [out, retval] _RootNodes**  pVal
);

Remarks

Use a RootNodes collection to iterate values of root nodes.

Example

The following example illustrates how to show the display name for each root node.

[Visual Basic]
Dim rns As RootNodes
Dim rn As RootNode
Dim strMsg As String
Set rns = EXTV1.GetRootNodes
For Each rn In rns
    strMsg = strMsg & rn.DisplayName & Chr(13)
Next
MsgBox "Root Nodes: " & Chr(13) & strMsg
© 2000-2001 Microsoft Corporation. All rights reserved.


GetSelectedNode Method

The GetSelectedNode method returns a TNode object of the selected node.

[Visual Basic]
Function GetSelectedNode() As TNode
[C++]
HRESULT GetSelectedNode(
    _TNode**  pVal
);
[IDL]
HRESULT GetSelectedNode(
    [out, retval] _TNode**  pVal
);

Remarks

Use a TNode object to get URLs and display names. This method returns nothing if a node is not selected.

Example

The following example displays the URL of a selected node.

[Visual Basic]
Dim Nd As TNode
Set Nd = EXTV1.GetSelectedNode
MsgBox Nd.url
© 2000-2001 Microsoft Corporation. All rights reserved.


MoveResource Method

The MoveResource method moves a folder to a location where it becomes the child folder of a destination folder.

[Visual Basic]
Function MoveResource(URLSource As String,
    URLNewParent As String,
    NewChildName As String
)
[C++]
HRESULT MoveResource(
    BSTR URLSource,
    BSTR URLNewParent,
    BSTR NewChildName
);
[IDL]
HRESULT MoveResource(
    [in] BSTR URLSource,
    [in] BSTR URLNewParent,
    [in] BSTR NewChildName
);
URLSource
The URL of the folder to move. This URL must be UTF encoded or derived from a TNode object.
URLNewParent
The folder that that contains the moved folder.
NewChildName
The location name of the moved folder.

Remarks

This method moves resources in the Web Storage System.

Example

The following example moves the selected node to be a child folder under the root.

[Visual Basic]
Dim tn As TNode
Set tn = EXTV1.GetSelectedNode
If tn.url <> tn.RootUrl Then
    EXTV1.MoveResource tn.url, tn.RootUrl, tn.DisplayName
End If
© 2000-2001 Microsoft Corporation. All rights reserved.


RefreshSelectedNode Method

The RefreshSelectedNode method updates the display of a selected node and its subordinate hierarchy.

[Visual Basic]
Function RefreshSelectedNode()
[C++]
HRESULT RefreshSelectedNode();
[IDL]
HRESULT RefreshSelectedNode();

Example

The following example refreshes the selected node.

[Visual Basic]
EXTV1.RefreshSelectedNode
© 2000-2001 Microsoft Corporation. All rights reserved.


RemoveAllNodes Method

The RemoveAllNodes method removes all nodes in the TreeView control.

[Visual Basic]
Function RemoveAllNodes()
[C++]
HRESULT RemoveAllNodes();
[IDL]
HRESULT RemoveAllNodes();

Remarks

Although this method removes all nodes, it does not affect any resources in the Web Storage System.

Example

The following example removes all nodes from the TreeView control.

[Visual Basic]
EXTV1.RemoveAllNodes
© 2000-2001 Microsoft Corporation. All rights reserved.


RemoveRootNode Method

The RemoveRootNode method removes a root node and its hierarchy from the TreeView control.

[Visual Basic]
Function RemoveRootNode(
    ByVal URL as String,
)
[C++]
HRESULT RemoveRootNode(
    BSTR URL
);
[IDL]
HRESULT GetRootNode(
    [in] BSTR URL
);
URL
A valid root URL to a root node. This URL must be UTFencoded or derived from a TNode object.

Remarks

This method only removes the root node from the TreeView control; it does not remove resources from the Web Storage System.

Example

The following example uses a TNode object to get the root node’s URL to remove theroot node.

[Visual Basic]
Dim tn As TNode
Set tn = EXTV1.GetSelectedNode
EXTV1.RemoveRootNode tn.RootUrl
© 2000-2001 Microsoft Corporation. All rights reserved.


SelectNode Method

The SelectNode method selects a specified node.

[Visual Basic]
Function SelectNode(
    ByVal URL as String,
)
[C++]
HRESULT SelectNode(
    BSTR* URL
);
[IDL]
HRESULT SelectNode(
    [in, out] BSTR* URL
);
URL
The URL of the node to select. This URL must be UTF-encoded or derived from a TNode object.

Example

The following example selects a specified node in the TreeView control.

[Visual Basic]
EXTV1.SelectNode "http://servername/Reports/Sales"


Events

This section describes events generated by TreeView control. You can trap these events and take appropriate programmatic action.


EXTVError Event

The EXTVError event provides error information when the TreeView control encounters an error condition.

 [Visual Basic]
Sub control_EXTVError(num As Long, desc As String, context As String)
)
Control
The name of the instantiated TreeView control as defined by the programmer. In Microsoft Visual Basic, the default name is EXTV1.
num
Error number.
desc
Error description.
context
Error contextual information.

Remarks

This event fires in special cases, such as a URL that is being redirected in the Web Storage System.

Example

The following example displays error information.

[Visual Basic]
Private Sub EXTV1_EXTVError(num As Long, desc As String, context As String)
    MsgBox num & " - " & desc & " - " & context
End Sub
© 2000-2001 Microsoft Corporation. All rights reserved.


NodeClick Event

The NodeClick event occurs when a node is clicked.

 [Visual Basic]
Sub control_NodeClick()
)
Control
The instance name of the Web Storage System TreeView control.

Example

The following example displays a node’s URL upon selection.

[Visual Basic]
Private Sub EXTV1_NodeClick()
    Dim tn As TNode
    Set tn = EXTV1.GetSelectedNode
    lbl1.Caption = tn.url
End Sub

SeeAlso

NodeSelected Event

© 2000-2001 Microsoft Corporation. All rights reserved.


NodeDragDrop Event

The NodeDragDrop event occurs when a drag-and-drop operation is completed.

[Visual Basic]
Sub control_NodeDragDrop(ByVal TNode As ExtreeView.TNode, ByVal x As Integer, ByVal y As Integer)
)
Control
The instance name of the Web Storage System TreeView control.
TNode
A TNode object of the dragged node.
X
The horizontal coordinate of the mouse pointer.
Y
The vertical coordinate of the mouse pointer.

Remarks

The mouse pointer coordinates are expressed in the unit of measurement determined by the standard Visual Basic ScaleMode property.

Example

The following example illustrates a node’s display name upon dragging.

[Visual Basic]
Private Sub EXTV1_NodeDragDrop(ByVal TNode As EXTreeView.TNode, ByVal x As Integer, ByVal y As Integer)
    MsgBox "You dragged " & TNode.DisplayName
End Sub
© 2000-2001 Microsoft Corporation. All rights reserved.


NodeDragStart Event

The NodeDragStart event occurs when a drag-and-drop operation is started.

[Visual Basic]
Sub control_NodeDragDrop(ByVal TNode As ExtreeView.TNode)
)
Control
The instance name of the Web Storage System TreeView control.
TNode
A TNode object of the dragged node.

Example

The following example illustrates a node’s display name upon dragging.

[Visual Basic]
Private Sub EXTV1_NodeDragDrop(ByVal TNode As EXTreeView.TNode)
    MsgBox "You are dragging " & TNode.DisplayName
End Sub
© 2000-2001 Microsoft Corporation. All rights reserved.


NodeRightClick Event

The NodeRightClick event occurs when a node is right-clicked.

 [Visual Basic]
Sub control_NodeRightClick(TNode As ExTreeView.TNode)
)
Control
The instance name of the Web Storage System TreeView control.
TNode
A TNode object of the right-clicked node.

Remarks

This event is useful for displaying pop-up menus.

Example

The following example illustrates a node’s root URL upon a right-click.

[Visual Basic]
Private Sub EXTV1_NodeClick(TNode As TNode)
    lbl1.Caption = TNode.RootURL
End Sub
© 2000-2001 Microsoft Corporation. All rights reserved.


NodeSelected Event

The NodeSelected event occurs when a node has changed.

 [Visual Basic]
Sub control_NodeSelected(TNode As ExTreeView.TNode)
)
Control
The instance name of the Web Storage System TreeView control.
TNode
A TNode object of the selected node.

Example

The following example illustrates a node’s URL upon selection.

[Visual Basic]
Private Sub EXTV1_NodeClick(TNode As TNode)
    lbl1.Caption = TNode.url
End Sub

Note The NodeClick event always fires when clicked; the NodeSelect event fires only when the selected node changes.

See Also

NodeClick Event

© 2000-2001 Microsoft Corporation. All rights reserved.


RootNode Collection

The Web Storage System TreeView control contains a Root Node object and Root Node collection. This section describes the properties and methods for the RootNode interfaces.

Root nodes are URLs to virtual directories in the Web Storage System, such as URLs to mailbox stores and public folders. New public folder trees must be configured as virtual directories using the Microsoft Exchange System Manager. Example URLs are shown in the following table.

Root node example URL | Description
http://servername/public | The default public folder tree, used by MAPI clients as installed by Microsoft Exchange 2000 Server.
http://servername/exchange/username | A private mailbox.
http://servername/pft_1 | A new public folder tree.
http://servername/pft_2 | A new public folder tree.

You can ascertain URLs, the display name, and authentication information from a Root Node object. Each root node can have its own authorization information.


AuthorizationNotRequired Property

The AuthorizationNotRequired property specifies whether authorization is not required to access a root node.

Applies To

RootNode object

 [Visual Basic,VBScript]
Property AuthorizationNotRequired as Boolean
[C++]
HRESULT get_AuthorizationNotRequired(VARIANT_BOOL* pVal);
HRESULT put_AuthorizationNotRequired(VARIANT_BOOL pVal);
[IDL]
HRESULT [propget] AuthorizationNotRequired([out,retval] VARIANT_BOOL* pVal);
HRESULT [propput] AuthorizationNotRequired([in] VARIANT_BOOL pVal);

Example

The following example illustrates whether authorization is not required to access the root node.

[Visual Basic]
Dim tn As TNode
Dim rn As RootNode
Set tn = EXTV1.GetSelectedNode
Set rn = EXTV1.GetRootNode(tn.RootUrl)
MsgBox rn.AuthorizationNotRequired
© 2000-2001 Microsoft Corporation. All rights reserved.


DisplayName Property

The DisplayName property is the root node’s display name.

Applies To

RootNode Object

[Visual Basic,VBScript]
Property DisplayNanme As String
[C++]
HRESULT get_DisplayName(BSTR* pVal);
HRESULT put_DisplayName(BSTR Val);
[IDL]
HRESULT [propget] DisplayName([out,retval] BSTR* pVal);
HRESULT [proput] DisplayNmae([in] BSTR Val);

Example

The following example illustrates the display name of the root node.

[Visual Basic]
Dim tn As TNode
Dim rn As RootNode
Set tn = EXTV1.GetSelectedNode
Set rn = EXTV1.GetRootNode(tn.RootUrl)
MsgBox rn.DisplayName
© 2000-2001 Microsoft Corporation. All rights reserved.


Count Property

The Count property returns the number of Node objects in the collection.

Applies To

RootNodes Collection

[Visual Basic]
Property Count as Long
read-only
[C++]
HRESULT get_Count(long* pVal);
[IDL]
HRESULT [propget] Count([out,retval] long* pVal);

Example

The following example displays the number of root nodes.

[Visual Basic]
Dim rns As RootNodes
Set rns = EXTV1.GetRootNodes
MsgBox rns.Count
© 2000-2001 Microsoft Corporation. All rights reserved.


Item Property

The Item property returns the BodyPart object specified by the index.

Applies To

RootNodes Collection

[Visual Basic]
Property Item(ByVal Index as Long) as RootNode
read-only
default
[C++]
HRESULT get_Item( VARIANT* Index,
    _RootNode** pVal);
[IDL]
HRESULT [propget,id(0)] Item([in] VARIANT* Index,
   [out,retval] _RootNode** pVal);

Remarks

Item is the default member on the interface.

Example

The following example enumerates the RootNodes collection using the Item property.

[Visual Basic]
Dim rns As RootNodes
Set rns = EXTV1.GetRootNodes
For x = 1 To rns.Count
   MsgBox rns.Item(x).url
Next
© 2000-2001 Microsoft Corporation. All rights reserved.


NewEnum Property

The NewEnum property returns an IEnumVARIANT interface on an Enumeration object for the collection. This property is hidden from Microsoft Visual Basic and Microsoft Visual Basic Scripting Edition (VBScript).

Applies To

RootNodes Collection

[Visual Basic]
Used automatically in For Each In constructs
[C++]
HRESULT get__NewEnum(IUnknown** pVal);
[IDL]
HRESULT [propget] _NewEnum([out,retval] IUnknown** pVal);

Remarks

This property is hidden within Visual Basic and VBScript. This property is a standard property used to support enumerating collections, for example following syntax in Visual Basic.

For Each Obj in Collection
  '
Next Obj

Example

The following example enumerates the RootNodes collection using NewEnum.

[Visual Basic]
Dim rns As RootNodes
Dim rn As RootNode
Set rns = EXTV1.GetRootNodes
For Each rn in rns
   MsgBox rn.DisplayName
Next
© 2000-2001 Microsoft Corporation. All rights reserved.


Password Property

The Password property is used to authenticate access to the root node.

Applies To

RootNode Object

[Visual Basic,VBScript]
Property Password As String
[C++]
HRESULT get_Password(BSTR* pVal);
HRESULT put_Password(BSTR pVal);
[IDL]
HRESULT [propget] Password([out,retval] BSTR* pVal);
HRESULT [proput] Password([in] BSTR pVal);

Remarks

This property is the password established by the administrator to a pubic or private store on Microsoft Exchange 2000 Server.

Example

The following example enumerates the RootNodes collection for empty passwords.

[Visual Basic]
Dim rns As RootNodes
Set rns = EXTV1.GetRootNodes
Dim rn As RootNode
For Each rn In rns
    If Len(rn.Password) = 0 Then
        MsgBox rn.DisplayName & " has an empty password"
    End If
Next
© 2000-2001 Microsoft Corporation. All rights reserved.


URL Property

The URL property is the URL of the root node.

Applies To

RootNode Object

[Visual Basic,VBScript]
Property URL As String
[C++]
HRESULT get_URL(BSTR* pVal);
HRESULT put_URL(BSTR pVal);
[IDL]
HRESULT [propget] URL([out,retval] BSTR* pVal);
HRESULT [proput] URL([in] BSTR pVal);

Example

The following example illustrates each root node’s URL.

[Visual Basic]
Dim rns As RootNodes
Set rns = EXTV1.GetRootNodes
Dim rn As RootNode
For Each rn In rns
    MsgBox rn.URL
Next
© 2000-2001 Microsoft Corporation. All rights reserved.


UserName Property

The UserName property is used to authenticate access to the root node.

Applies To

RootNode Object

[Visual Basic,VBScript]
Property UserName As String
[C++]
HRESULT get_UserName(BSTR* pVal);
HRESULT put_UserName(BSTR pVal);
[IDL]
HRESULT [propget] UserName([out,retval] BSTR* pVal);
HRESULT [proput] UserName([in] BSTR pVal);

Example

The following example illustrates each root node’s username.

[Visual Basic]
Dim rns As RootNodes
Set rns = EXTV1.GetRootNodes
Dim rn As RootNode
For Each rn In rns
    MsgBox rn.UserName
Next
© 2000-2001 Microsoft Corporation. All rights reserved.


Add Method

The Add method adds a root node to the collection.

Warning This method is for future use and will fail in its current implantation. Instead, use the EXTV AddRootNode method.


TNode Interface

The TNode interface provides URL and display name information for any node in the hierarchy. This interface is typically used to get a URLs for using methods that work with nodes, such as the GetRootNode method.


DisplayName Property

The DisplayName property is a node’s display name.

[Visual Basic,VBScript]
Property DisplayName As String
[C++]
HRESULT get_DisplayName(BSTR* pVal);
HRESULT put_DisplayName(BSTR pVal);
[IDL]
HRESULT [propget] DisplayName([out,retval] BSTR* pVal);
HRESULT [proput] DisplayNmae([in] BSTR pVal);

Remarks

This property does not affect or correspond to any property in the Web Storage System.

Example

The following example illustrates the display name of a selected node.

[Visual Basic]
Dim tn As TNode
Set tn = EXTV1.GetSelectedNode
MsgBox tn.DisplayName
© 2000-2001 Microsoft Corporation. All rights reserved.


ParentURL Property

The ParentURL property is the URL to node’s parent.

[Visual Basic,VBScript]
Property ParentURL As String
[C++]
HRESULT get_ParentURL(BSTR* pVal);
HRESULT put_ParentURL(BSTR pVal);
[IDL]
HRESULT [propget] ParentURL([out,retval] BSTR* pVal);
HRESULT [proput] ParentURL([in] BSTR pVal);

Example

The following example illustrates the parent URL of a selected node.

[Visual Basic]
Dim tn As TNode
Set tn = EXTV1.GetSelectedNode
MsgBox tn.ParentURL
© 2000-2001 Microsoft Corporation. All rights reserved.


RootURL Property

The RootURL property is the URL of a node’s root.

[Visual Basic,VBScript]
Property RootURL As String
[C++]
HRESULT get_RootURL(BSTR* pVal);
HRESULT put_RootURL(BSTR pVal);
[IDL]
HRESULT [propget] RootURL([out,retval] BSTR* pVal);
HRESULT [proput] RootURL([in] BSTR pVal);

Example

The following example illustrates root URL of a selected node.

[Visual Basic]
Dim tn As TNode
Set tn = EXTV1.GetSelectedNode
MsgBox tn.DisplayName
© 2000-2001 Microsoft Corporation. All rights reserved.


URL Property

The URL property is a node’s UTF-8 encoded URL.

[Visual Basic,VBScript]
Property URL As String
[C++]
HRESULT get_URL(BSTR* pVal);
HRESULT put_URL(BSTR pVal);
[IDL]
HRESULT [propget] URL([out,retval] BSTR* pVal);
HRESULT [proput] URL([in] BSTR pVal);

Example

The following example illustrates the URL of a selected node.

[Visual Basic]
Dim tn As TNode
Set tn = EXTV1.GetSelectedNode
MsgBox tn.URL
© 2000-2001 Microsoft Corporation. All rights reserved.


atFunction Interfaces

This section of the Web Storage System SDK helps developers understand and use the methods of the atFunction interfaces. The atFunction interfaces, which address most of the @functions available in Lotus Notes, help Lotus Notes developers work in the Microsoft® Exchange 2000 Server application environment.


Overview

The atFunction interfaces were created to help Lotus Notes developers migrate applications into the Exchange 2000 Server environment. In particular these interfaces help developers move application logic from Notes to Exchange without redesigning existing applications, and they allow developers to add enhancements that the Exchange environment makes possible.

The atFunctions are implemented within COM interfaces in a library called MXAT.dll. This DLL must be installed on the computer where any script or program using the atFunctions will be run.

Although all original @functions from Lotus Notes are addressed in this document, only the ones that make sense in the Exchange application environment are implemented within MXAT.dll. The Lotus Notes application environment is different from that of Exchange in many ways. For example, the @DBLookup function for Notes databases is not implemented in MXAT.dll because in the Exchange environment data is stored in data storage systems other than Lotus Notes. Another example is the @Platform function, which on a Notes installation returns the version of Notes under which the script is running. This functionality would make no sense in the environment of Exchange.

You can use the atFunction interfaces not only for migration, but also to provide general functionality for working with objects in the Web Storage System. Anything you can access through COM is suited for use with the atFunction interfaces. You can use the atFunction interfaces with any programming language that supports COM, such as Microsoft Visual Basic®, Visual Basic Scripting Edition (VBScript), Visual C++®, JScript®, and C#.


atFunction Object Model

The MXAT DLL contains three stand-alone objects. You can instantiate and use any of them in your code depending on which object model you are working with. The three atFunction objects implemented for Microsoft Exchange 2000 Server are as follows:

  • The MXOLAT object is used with Microsoft Outlook® items.
  • The MXCDOAT object is used with Collaboration Data Objects (CDO) items.
  • The MXADOAT object is used with ActiveX® Data Objects (ADO) items.

This model gives you the flexibility to use most of the implemented atFunction methods with any object model you choose. Installing and Registering the atFunctions DLL describes how to install and register the object interfaces.


Using the atFunctions

This section describes two aspects of programming with the atFunction interfaces:

  • Object Model Flexibility describes how the atFunction interfaces work with the primary object models used with Microsoft Exchange 2000 Server and the Web Storage System: Outlook, CDO, and ADO.
  • About Data Types describes differences in how Lotus Notes and Microsoft Exchange 2000 Server indicate data types.

Object Model Flexibility

Most of the atFunction methods are available to more than one of the three object models—Outlook, CDO, and ADO. In such cases, the atFunction provides the same functionality in each object model, although many of these functions differ according to the type of data they work with. For example, the Outlook version of a function might require an Outlook Item object, the ADO version might require a Record object, and the CDO version might require a Message or an AppointmentItem object. You can specify the correct item by setting the CurrentItem property before calling the atFunction method.

Some functions are available for only one or two of the object models. When this is the case, you see a note to that effect in the description of the function in the atFunction Reference.

About Data Types

Lotus Notes has the concept of lists; the Microsoft atFunctions use arrays instead. Where a Notes @function has a list as its parameter, the atFunction requires an array (typically passed as a Variant).

Examples of different data requirements are:

  • Where the Notes @function requires a text or text list, the equivalent atFunction requires a string or an array of strings.
  • Where the Notes @function requires a number, the equivalent atFunction requires a Visual Basic numeric data type such as a Long.
  • Where the Notes @function requires a number list, the equivalent atFunction requires an array of numeric values (such as Longs).

While some atFunctions technically can be passed Variants, they will not function properly unless data of the correct, more specific type is passed. For example, if the original Notes @function required a text list, you need to pass an array of strings to the Microsoft atFunction method.

Data Types in atFunction References

The return values of the atFunction methods are given in the Syntax section of each method description. For example, the syntax for the atDay method is shown as follows:

Integer = atDay(DateVal As Date)

This shows that the return value for atDay is an Integer. It also shows that the function's one parameter, DateVal, is of the Date data type.

Some of the atFunction methods are not functions, but subroutines, such as the following:

Sub atError()

Because a subroutine does not return data, its syntax section shows no return value data type.


Installing and Registering the atFunctions DLL

The atFunction interfaces are implemented within COM objects in a library called MXAT.dll. This DLL must be installed on the computer where any script or program using the atFunctions will be run.

To set up the atFunction interfaces

  1. Install the MXAT.dll library by installing the Web Storage System SDK. (In the installation wizard for this SDK, first choose Custom setup. On the Custom Setup page of the wizard, expand Web Storage System SDK and then expand Support. Under the Support node, select atFunctions.) In an environment other than the Web Storage System SDK, register the MXAT.dll library separately. To do this, copy the MXAT.dll file into the Windows system directory and then type regssvr32 mxat.dll at a command prompt.
  2. Make the atFunction interfaces available to your programming environment. If you are using Visual Basic, for example, you will need to select the MXAT library as a reference. To do this, click References on the Project menu. Under Available References, select the check box next to Microsoft Exchange Component for Lotus Notes @functions.
  3. Use atFunction method calls in your code. For examples, see Sample Code for the Outlook Object Model, Sample Code for the CDO Object Model, and Sample Code for the ADO Object Model.


Sample Code for the Outlook Object Model

This sample code uses atFunctions to change the body of a message. It calls the atTrim and atProperCase functions to change the text appearance in the body of a message. It also calls the atVersion and atNow functions to append the version of Microsoft Outlook and the date and time to the message body.

'Language = VBScript

'******************************************
'*Sample Code for the outlook object model*
'**************************************** *
'This code should go into the script window of an outlook form...

Dim objAT

Function Item_Open()

    Set objAT = CreateObject("MXAT.MXOLAT")
    Set objAT.CurrentItem = Item

End Function

Function Item_Send()

    'prefix the message body with a the current outlook version and the current time , and make the message body
    'proper case after trimming spaces from it
    With objAt
        Item.Body = "Message sent using Microsoft Outlook version " & .atVersion & "at " & .atNow & vbcrlf & _
            .atTrim(.atProperCase(Item.Body))
    End With

End Function

Function Item_Close()

    Set objAT.CurrentItem = Nothing
    Set objAT = Nothing

End Function

© 2000-2001 Microsoft Corporation. All rights reserved.


Sample Code for the CDO Object Model

The function shown in the following sample code takes a CDO object as its only parameter. It then calls the atAttachmentNames method to determine the file names of all attachments on the object, and returns the results of that method call. This function returns its result in a Variant array.

'************************************
'*Sample Code for the CDO version
'************************************
'

Function AttachmentNames(objMessage)
    'Function takes a CDO Message, MeetingItem, or AppointmentItem Object
    'as parameter and returns the names of its attachments as a variant array

    Dim objAt, i

    Set objAt = CreateObject("MXAT.MXCDOAT")
    Set objAt.CurrentItem = objMessage

    AttachmentNames = objAt.atAttachmentNames

    Set objAt.CurrentItem = Nothing
    Set objAt = Nothing

End Function

© 2000-2001 Microsoft Corporation. All rights reserved.


Sample Code for the ADO Object Model

The function shown in the following sample code takes an ADO record object as its only parameter. This record object refers to an item residing in the Web Storage System. The function then calls the atModified method to determine when the item was last saved; atModified returns a date. The ModifiedTime function then returns that date value.

'************************************
'*Sample Code for the ADO version
'************************************
'

Function ModifiedTime(objRecord)
    'Function takes a ADO Record Object (pointing to a Web Storage System Item)
    'as parameter and returns its Last Modified Time

    Dim objAt, i

    Set objAt = CreateObject("MXAT.MXADOAT")
    Set objAt.CurrentItem = objRecord

    ModifiedTime = objAt.atModified

    Set objAt.CurrentItem = Nothing
    Set objAt = Nothing

End Function

© 2000-2001 Microsoft Corporation. All rights reserved.


atFunction Reference

The atFunction method descriptions contain several parts:

  • Following the name of the method is a brief description of its purpose.
  • The Availability section states from which object models (Outlook, CDO, or ADO) the method can be called.
  • The Syntax section shows the method's return value and parameters.
  • Any additional notes are presented in a Usage Notes section.

Functions Organized by Type

The atFunctions perform several different types of tasks. The following table orders the atFunctions by functional type.

Type | atFunction method
Strings and characters | atAbstract, atBegins, atChar, atContains, atEnds, atExplode, atImplode, atIsMember, atIsNotMember, atIsText, atKeywords, atLeft, atLeftBack, atLength, atLike, atLowerCase, atMiddle, atMiddleBack, atNewLine, atProperCase, atRepeat, atReplace, atReplaceSubstring, atRight, atRightBack, atText, atTrim, atUpperCase, atWord, Concat
Numbers | atAbs, atExp, atInteger, atIsNumber, atLn, atLog, atMax, atMember, atMin, atModulo, atPi, atPower, atRandom, atRound, atSign, atSqrt, atSum, atTextToNumber, atUnique
Other mathematical types (including logical) | atAcos, atAll, atAsin, atAtan, atAtan2, atCos, atElements, atFalse, atIsText, atIsNumber, atIsTime, atNo, atSin, atSuccess, atTan, atTrue, atYes
Dates and times | atAdjust, atDate, atDay, atHour, atIsTime, atMinute, atModified, atMonth, atNow, atSecond, atTextToTime, atTime, atToday, atTomorrow, atWeekday, atYear, atYesterday, atZone
Documents and other database objects | atAccessed, atAttachmentNames, atAttachments, atAuthor, atCreated, atDbColumn, atDbCommand, atDbLookup (ODBC), atDbName, atDbTitle, atDocLength, atDocumentUniqueId, atGetDocField, atIsAvailable, atIsDocBeingEdited, atIsNewDoc, atIsUnavailable, atMailSavePreference, atMailSend, atModified, atNoteID, atSetDocField, atSetField
System entities such as user names or product versions | atUserName, atV3UserName, atVersion, atZone, CurrentItem property
URLs | atURLGetHeader, atURLHistory, atURLOpen
Other | atError, atPrompt, atSelect, atSubset, atViewTitle
Not implemented | atAllChildren, atAllDescendants, atAscii, atAttachmentLengths, atCertificate, atCheckAlarms, atClientType, atCommand, atDbExists, atDbLookup (Notes databases), atDbManager, atDDEExecute, atDDEInitiate, atDDEPoke, atDDETerminate, atDEFAULT, atDeleteDocument, atDeleteField, atDialogBox, atDo, atDocChildren, atDocDescendants, atDocFields, atDocLevel, atDocMark, atDocNumber, atDocParentNumber, atDocSiblings, atDomain, atEditECL, atEditUserECL, atEnableAlarms, atEnvironment, ENVIRONMENT, atFailure, FIELD, atGetPortsList, atGetProfileField, atIf, atInheritedDocumentUniqueID, atIsAgentEnabled, atIsCategory, atIsDocBeingLoaded, atIsDocBeingMailed, atIsDocBeingRecalculated, atIsDocBeingSaved, atIsDocTruncated, atIsError, atIsExpandable, atIsModalHelp, atIsResponseDoc, atIsValid, atMailDbName, atMailEncryptSavedPreference, atMailEncryptSentPreference, atMailSignPreference, atMatches, atName, atOptimizeMailAddress, atPassword, atPickList, atPlatform, atPostedCommand, atRefreshECL, REM, atResponses, atReturn, SELECT, atSet, atSetEnvironment, atSoundex, atTextToNumber, atTextToTime, atUnavailable, atUserAccess, atUserPrivileges, atUserRoles, atV2If


atAbs

This method returns the absolute value (unsigned value) of a number.

Availability

This method is available in the following object models: Outlook, CDO, and ADO.

Syntax

Double = atAbs(Number As Double)


atAbstract

This method abbreviates the contents of text passed in.

Availability

This method is available in the following object models: Outlook, CDO, and ADO.

Syntax

String = atAbstract(Commands As String, Size As Long, BeginText As String, TextToAbstract)


atAccessed

This method indicates the time and date when the item was last modified.

Availability

This method is available in the following object models: Outlook, CDO, and ADO.

Syntax

Date = atAccessed()


atAcos

This method calculates the arccosine (inverse cosine), given the cosine of an angle.

Availability

This method is available in the following object models: Outlook, CDO, and ADO.

Syntax

Double = atAcos(Cosine As Double)


atAdjust

This method adjusts the specified date-time value (Date data type) by the interval specified.

Availability

This method is available in the following object models: Outlook, CDO, and ADO.

Syntax

Date = atAdjust(DateToAdjust As Date, Years As Integer, Months As Integer, Days As Integer, Hours As Integer, Minutes As Integer, Seconds As Integer, [DST As String = "[InGMT]"])

Usage Notes

This method ignores the optional time zone parameter (DST).


atAll

This method returns the value True.

Availability

This method is available in the following object models: Outlook, CDO, and ADO.

Syntax

Boolean = atAll()


atAllChildren

This method is not implemented. Calling it would raise a run-time error.


atAllDescendants

This method is not implemented. Calling it would raise a run-time error.


atAscii

This method is not implemented. Calling it would raise a run-time error.


atAsin

This method calculates the arcsine (inverse sine), given the sine of an angle.

Availability

This method is available in the following object models: Outlook, CDO, and ADO.

Syntax

Double = atAsin(Sine As Double)


atAtan

This method returns the arctangent (inverse tangent), given the tangent of an angle.

Availability

This method is available in the following object models: Outlook, CDO, and ADO.

Syntax

Double = atAtan(Angle As Double)


atAtan2

This method returns the arctangent (inverse tangent), using the tangent y/x of an angle.

Availability

This method is available in the following object models: Outlook, CDO, and ADO.

Syntax

Double = atAtan2(X As Double, Y As Double)


atAttachmentLengths

This method is not implemented. Calling it would raise a run-time error.


atAttachmentNames

This method returns the file names of any files attached to a document.

Availability

This method is available in the following object models: Outlook and CDO.

Syntax

Variant = atAttachmentNames()

This method can return a string or a string array, in which each string is the name of an attached file.


atAttachments

This method returns the number of attachments in the item.

Availability

This method is available in the following object models: Outlook and CDO.

Syntax

Long = atAttachments()


atAuthor

This method returns the name of the author of the current item.

Availability

This method is available in the following object models: Outlook, CDO, and ADO.

Syntax

String = atAuthor()


atBegins

This method determines whether a particular string occurs at the beginning of another string.

Availability

This method is available in the following object models: Outlook, CDO, and ADO.

Syntax

Boolean = atBegins(StringToCheckIn As String, SubString)


atCertificate

This method is not implemented. Calling it would raise a run-time error.


atChar

This method returns the character corresponding to an ASCII value passed.

Availability

This method is available in the following object models: Outlook, CDO, and ADO.

Syntax

String = atChar(CharCode As Long)


atCheckAlarms

This method is not implemented. Calling it would raise a run-time error.


atClientType

This method is not implemented. Calling it would raise a run-time error.


atCommand

This method is not implemented. Calling it would raise a run-time error.


atContains

This method determines whether a particular string occurs in another string or string array.

Availability

This method is available in the following object models: Outlook, CDO, and ADO.

Syntax

Boolean = atContains(StringToCheckIn As String, SubString)

Usage Notes

If SubString is a string array, this method returns the value True if any of the strings passed in that array contain StringToCheckIn.


atCos

Given an angle in radians, this method returns the cosine of the angle.

Availability

This method is available in the following object models: Outlook, CDO, and ADO.

Syntax

Double = atCos(Angle As Double)


atCreated

This method returns the date-time (Date data type) when the document was created.

Availability

This method is available in the following object models: Outlook, CDO, and ADO.

Syntax

Date = atCreated()


atDate

This method translates numbers in a parameter array for their various time and date components and then returns the date-time value (Date data type).

Availability

This method is available in the following object models: Outlook, CDO, and ADO.

Syntax

Date = atDate(DateValue As Date)

Date = atDate(Years As Integer, Months As Integer, Days As Integer)

Date = atDate(Years As Integer, Months As Integer, Days As Integer, Hours As Integer, Minutes As Integer, Seconds As Integer)

Usage Notes

The Syntax section lists three different syntax models for this method. You can use any one of them because all three are valid.


atDay

This method extracts and returns the day of the month from the specified date.

Availability

This method is available in the following object models: Outlook, CDO, and ADO.

Syntax

Integer = atDay(DateVal As Date)


atDbColumn

This method accesses a specified data source to locate a specified DBMS, table, and column and returns a list of all the rows in that column. It can be used only with ODBC data sources registered on the computer on which the MXAT library is registered.

Availability

This method is available in the following object models: Outlook, CDO, and ADO.

Syntax

Variant = atDbColumn(KeywordString As String, DataSourceName As String, UserIds, Passwords, Table As String, Column As String, NullHandling, [DistinctSort])

This method returns a String, a number value (Integer or Long), a Date value, or an array of any of these types.


atDbCommand

This method executes a SQL SELECT statement on the specified data source and returns a list of all the rows from the specified column.

Availability

This method is available in the following object models: Outlook, CDO, and ADO.

Syntax

Variant = atDbCommand(KeywordString As String, DataSourceName As String, UserIds, Passwords, CommandString As String, NullHandling)

This method returns a String, a number value (Integer or Long), a Date value, or an array of any of these types.


atDbExists

This method is not implemented. Calling it would raise a run-time error.


atDbLookup (Notes databases)

This method is not implemented. Calling it would raise a run-time error.


atDbLookup (ODBC)

This method uses data source information to locate a specified column, and then fetches all rows from the specified column in the given data source matching the given condition.

Availability

This method is available in the following object models: Outlook, CDO, and ADO.

Syntax

Variant = atDbLookup(KeywordString As String, DataSourceName As String, UserIds, Passwords, Table As String, Column As String, NullHandling As String, KeyColumn As String, KeyValue, [DistinctSort])

This method returns a String, a number value (Integer or Long data type), a Date value, or an array of any of these types.


atDbManager

This method is not implemented. Calling it would raise a run-time error.


atDbName

This method returns the name of the folder in which the current item is present. This method is equivalent to the atDbTitle method.

Availability

This method is available in the following object models: Outlook, CDO, and ADO.

Syntax

String = atDbName()


atDbTitle

This method returns the name of the folder in which the current item is present. This method is equivalent to the atDbName method.

Availability

This method is available in the following object models: Outlook, CDO, and ADO.

Syntax

String = atDbTitle()


atDDEExecute

This method is not implemented. Calling it would raise a run-time error.


atDDEInitiate

This method is not implemented. Calling it would raise a run-time error.


atDDEPoke

This method is not implemented. Calling it would raise a run-time error.


atDDETerminate

This method is not implemented. Calling it would raise a run-time error.


atDEFAULT

This method is not implemented. Calling it would raise a run-time error.


atDeleteDocument

This method is not implemented. Calling it would raise a run-time error.


atDeleteField

This method is not implemented. Calling it would raise a run-time error.


atDialogBox

This method is not implemented. Calling it would raise a run-time error.


atDo

This method is not implemented. Calling it would raise a run-time error.


atDocChildren

This method is not implemented. Calling it would raise a run-time error.


atDocDescendants

This method is not implemented. Calling it would raise a run-time error.


atDocFields

This method is not implemented. Calling it would raise a run-time error.


atDocLength

This method returns the size of an item in bytes.

Availability

This method is available in the following object models: Outlook, CDO, and ADO.

Syntax

Long = atDocLength()


atDocLevel

This method is not implemented. Calling it would raise a run-time error.


atDocMark

This method is not implemented. Calling it would raise a run-time error.


atDocNumber

This method is not implemented. Calling it would raise a run-time error.


atDocParentNumber

This method is not implemented. Calling it would raise a run-time error.


atDocSiblings

This method is not implemented. Calling it would raise a run-time error.


atDocumentUniqueId

This method returns a unique ID for the current document.

Availability

This method is available in the following object models: Outlook, CDO, and ADO.

Syntax

String = atDocumentUniqueId()


atDomain

This method is not implemented. Calling it would raise a run-time error.


atEditECL

This method is not implemented. Calling it would raise a run-time error.


atEditUserECL

This method is not implemented. Calling it would raise a run-time error.


atElements

This method calculates the number of elements or values in a list (array).

Availability

This method is available in the following object models: Outlook, CDO, and ADO.

Syntax

Long = atElements(ListOfValues)


atEnableAlarms

This method is not implemented. Calling it would raise a run-time error.


atEnds

This method determines whether a particular string occurs at the end of another string (case-sensitive).

Availability

This method is available in the following object models: Outlook, CDO, and ADO.

Syntax

Boolean = atEnds(StringToCheck As String, SubString)

The Substring parameter can be a string or a string array, in which case the function would return the value True if StringToCheck ends with any of the strings in the array.


atEnvironment

This method is not implemented. Calling it would raise a run-time error.


ENVIRONMENT

This method is not implemented. Calling it would raise a run-time error.


atError

This method intentionally raises a run-time error.

Availability

This method is available in the following object models: Outlook, CDO, and ADO.

Syntax

Sub atError()


atExp

This method calculates the number e (approximately 2.718282) raised to the specified value of the Power parameter.

Availability

This method is available in the following object models: Outlook, CDO, and ADO.

Syntax

Double = atExp(Power As Double)


atExplode

This method returns a string or an array of strings composed of the elements of a string or date range based on whether the input is a string or a string containing a date range (in the format “Date1 – Date2”)..

Availability

This method is available in the following object models: Outlook, CDO, and ADO.

Syntax

Variant = atExplode(StringtoExplode, [Separators As String = " ,;"], [IncludeEmpties As Boolean = True])

This method can return a string, a string array, a date array, or an array containing strings and dates, depending on the parameters passed.


atFailure

This method is not implemented. Calling it would raise a run-time error.


atFalse

This method returns the value False. This method is equivalent to the atNo method.

Availability

This method is available in the following object models: Outlook, CDO, and ADO.

Syntax

Boolean = atFalse()


FIELD

This method is not implemented. Calling it would raise a run-time error.


atGetDocField

This method returns the value stored in the specified field in the item with the specified EntryID.

Availability

This method is available in the following object models: Outlook, CDO, and ADO.

Syntax

Variant = atGetDocField(EntryID As String, Field As String)

This method can return a string or a string array.

Usage Notes

You can obtain the EntryID of the current document by calling the atDocumentUniqueId method.


atGetPortsList

This method is not implemented. Calling it would raise a run-time error.


atGetProfileField

This method is not implemented. Calling it would raise a run-time error.


atHour

This method extracts and returns the hour of the day from the TimeVal parameter.

Availability

This method is available in the following object models: Outlook, CDO, and ADO.

Syntax

Integer = atHour(TimeVal As Date)


atIf

This method is not implemented. Calling it would raise a run-time error.


atImplode

This method concatenates all members of a text list and returns a string or array of strings.

Availability

This method is available in the following object models: Outlook, CDO, and ADO.

Syntax

String = atImplode(TextList, [Separator As String = " "])

Usage Notes

You need to use the Concat method in conjunction with the atImplode method.

Say you have a Lotus Notes form that contains a field named Cities and another field named Capitals. Calling the Notes @Implode function as shown here

@Implode (Capitals + “/” + Cities)

takes one element from each field, adds a slash, generates a cross product (combines every member of one list with every member of the other list), and returns a text list. For example, if the Capitals field contains the string "Capitals" and the Cities field contains "Paris" and "London", the result would be these strings: "Capitals / Paris", "Capitals / London".

To do this using the atImplode atFunction, you need to also use the Concat method, which is available on all three objects of the MXAT library. The following example shows how to use atImplode and Concat together:

Variant1 = AtObject.atImplode(AtObject.Concat(Item.UserProperties(“Capitals”).Value, AtObject.Concat(“/”, Item.UserProperties(“Cities”)))


atInheritedDocumentUniqueID

This method is not implemented. Calling it would raise a run-time error.


atInteger

This method truncates the values in a number (or an array of numbers) at the whole number, excluding any decimal parts.

Availability

This method is available in the following object models: Outlook, CDO, and ADO.

Syntax

Variant = atInteger(NumberList)

This method returns a number (Integer or Long data type) or an array of numbers.


atIsAgentEnabled

This method is not implemented. Calling it would raise a run-time error.


atIsAvailable

This method returns the value True if the current item contains a field of the given name.

Availability

This method is available in the following object models: Outlook, CDO, and ADO.

Syntax

Boolean = atIsAvailable(Field)


atIsCategory

This method is not implemented. Calling it would raise a run-time error.


atIsDocBeingEdited

This method always returns the value True in the Outlook version; it is not available for CDO and ADO.

Availability

This method is available in the following object models: Outlook.

Syntax

Boolean = atIsDocBeingEdited()


atIsDocBeingLoaded

This method is not implemented. Calling it would raise a run-time error.


atIsDocBeingMailed

This method is not implemented. Calling it would raise a run-time error.


atIsDocBeingRecalculated

This method is not implemented. Calling it would raise a run-time error.


atIsDocBeingSaved

This method is not implemented. Calling it would raise a run-time error.


atIsDocTruncated

This method is not implemented. Calling it would raise a run-time error.


atIsError

This method is not implemented. Calling it would raise a run-time error.


atIsExpandable

This method is not implemented. Calling it would raise a run-time error.


atIsMember

This method returns the value True if all members of a specified string or string array are present in a specified target string or array of strings (case-sensitive).

Availability

This method is available in the following object models: Outlook, CDO, and ADO.

Syntax

Boolean = atIsMember(TextListToSearchFor, TextListToSearchIn)


atIsModalHelp

This method is not implemented. Calling it would raise a run-time error.


atIsNewDoc

This method returns the value True if the current item has never been saved.

Availability

This method is available in the following object models: Outlook, CDO, and ADO.

Syntax

Boolean = atIsNewDoc()


atIsNotMember

This method returns the value True if no member of the specified string or string array is present in a specified target string or array of strings (case-sensitive).

Availability

This method is available in the following object models: Outlook, CDO, and ADO.

Syntax

Boolean = atIsNotMember(TextListToSearchFor, TextListToSearchIn)


atIsNumber

This method returns the value True if the specified value is a number or array of numbers.

Availability

This method is available in the following object models: Outlook, CDO, and ADO.

Syntax

Boolean = atIsNumber(NumberList)


atIsResponseDoc

This method is not implemented. Calling it would raise a run-time error.


atIsText

This method returns True if the specified argument is a string or string array.

Availability

This method is available in the following object models: Outlook, CDO, and ADO.

Syntax

Boolean = atIsText(TextList)


atIsTime

This method returns the value True if the specified argument is a date-time value (Date data type) or a comma- or semicolon-delimited date-time list (an array of values of the Date data type).

Availability

This method is available in the following object models: Outlook, CDO, and ADO.

Syntax

Boolean = atIsTime(DateTimeList)


atIsUnavailable

This method returns the value False if the current item has a field of the given name.

Availability

This method is available in the following object models: Outlook, CDO, and ADO.

Syntax

Boolean = atIsUnavailable(Field)


atIsValid

This method is not implemented. Calling it would raise a run-time error.


atKeywords

Given two strings or an array of strings (referred to here as "word lists"), this method searches through the first word list and returns a list of words from the second word list that are also found in the first.

Availability

This method is available in the following object models: Outlook, CDO, and ADO.

Syntax

Array of Strings = atKeywords(TextListToLookIn, TextlistToLookFor, [Delimiters As String = "" ,?!;:[](){}<>"])


atLeft

For SearchParameter = n, a number, this method searches left to right and returns the leftmost n characters in the string; if SearchParameter is a string, it returns all the characters to the left of the first occurrence of the search parameter string.

Availability

This method is available in the following object models: Outlook, CDO, and ADO.

Syntax

String = atLeft(StringToLookIn As String, SearchParameter)


atLeftBack

For SearchParameter = n, a number, this method searches a string from right to left and returns all but the last n characters in the string; if SearchParameter is a string, it returns all the characters to the left of the last occurrence of the search parameter string.

Availability

This method is available in the following object models: Outlook, CDO, and ADO.

Syntax

String = atLeftBack(StringToLookIn As String, SearchParameter)


atLength

If the parameter is a string, atLength returns the number of characters in the string. If the parameter is an array of strings, atLength searches the array and returns the number of characters in each string, as an array of numbers.

Availability

This method is available in the following object models: Outlook, CDO, and ADO.

Syntax

Variant = atLength(StringList)

This method returns a number (Integer or Long data type) or an array of numbers.


atLike

This method returns the value True if a string matches a specified pattern.

Availability

This method is available in the following object models: Outlook, CDO, and ADO.

Syntax

Boolean = atLike(StringToProcess As String, Pattern As String, [EscapeCharacter])


atLn

This method returns the natural logarithm of the specified number.

Availability

This method is available in the following object models: Outlook, CDO, and ADO.

Syntax

Double = atLn(Number As Double)


atLog

This method returns the logarithm (to the base 10) of the specified number.

Availability

This method is available in the following object models: Outlook, CDO, and ADO.

Syntax

Double = atLog(Number As Double)


atLowerCase

This method converts all uppercase letters to lowercase in the specified string. Compare with the atProperCase method.

Availability

This method is available in the following object models: Outlook, CDO, and ADO.

Syntax

String = atLowerCase(StringToConvert As String)


atMailDbName

This method is not implemented. Calling it would raise a run-time error.


atMailEncryptSavedPreference

This method is not implemented. Calling it would raise a run-time error.


atMailEncryptSentPreference

This method is not implemented. Calling it would raise a run-time error.


atMailSavePreference

This method returns a Boolean that indicates whether sent mail should be stored in the Sent Messages folder.

Availability

This method is available in the following object models: Outlook.

Syntax

Boolean = atMailSavePreference()


atMailSend

This method sends the current item, or composes a new mail message and sends it, based on parameters passed.

Availability

This method is available in the following object models: Outlook and CDO.

Syntax

Sub atMailSend([SendTo], [CopyTo], [BlindCopyTo], [Subject As String], [Remark As String], [BodyFields], [Flags])


atMailSignPreference

This method is not implemented. Calling it would raise a run-time error.


atMatches

This method is not implemented. Calling it would raise a run-time error.


atMax

Given two numbers, this method returns the larger of the two. If arrays of numbers are passed as parameters, the function returns a pair-wise computation of the arrays.

Availability

This method is available in the following object models: Outlook, CDO, and ADO.

Syntax

Variant = atMax(NumberList1, NumberList2)

This method returns a number (Integer or Long data type) or an array of numbers.


atMember

This method returns the position of a value in a list; it returns -1 if the value is not found.

Availability

This method is available in the following object models: Outlook, CDO, and ADO.

Syntax

Long = atMember(StringToSearch As String, TextListToSearchIn)


atMiddle

This method returns a string containing a specified set of characters (a substring) from the middle of a string. The StartParam and EndParam parameters delimit the middle of the string.

The difference between this method and the atMiddleBack method is that atMiddle finds the middle of the string by searching left to right while atMiddleBack searches right to left.

Availability

This method is available in the following object models: Outlook, CDO, and ADO.

Syntax

String = atMiddle(StringToSearch As String, StartParam, EndParam)


atMiddleBack

This method returns a string containing a specified set of characters (a substring) from the middle of a string. The StartParam and EndParam parameters delimit the middle of the string.

The difference between this method and the atMiddle method is that atMiddleBack finds the middle of the string by searching right to left while atMiddle searches left to right.

Availability

This method is available in the following object models: Outlook, CDO, and ADO.

Syntax

String = atMiddleBack(StringToSearch As String, StartParam, EndParam)


atMin

This method returns the lesser of two numbers. If arrays of numbers are passed, it performs a pair-wise computation.

Availability

This method is available in the following object models: Outlook, CDO, and ADO.

Syntax

Variant = atMin(NumberList1, NumberList2)

This method returns a number (Integer or Long data type) or an array of numbers.


atMinute

This method returns the minute value from the specified date-time value (Date data type).

Availability

This method is available in the following object models: Outlook, CDO, and ADO.

Syntax

Integer = atMinute(TimeVal As Date)


atModified

This method returns a date-time value (Date data type) indicating when the document was last edited and saved.

Availability

This method is available in the following object models: Outlook, CDO, and ADO.

Syntax

Date = atModified()


atModulo

Given two numbers, this method returns the remainder of dividing the first number by the second.

Availability

This method is available in the following object models: Outlook, CDO, and ADO.

Syntax

Variant = atModulo(NumberList1, NumberList2)

This method returns a number (Integer or Long data type) or an array of numbers.

Usage Notes

If arrays of numbers are passed as parameters, the function returns a pair-wise computation of the arrays. If the arrays have a different number of elements, the missing elements (elements in one array for which there is no corresponding element in the other array) are treated as zero.


atMonth

This method extracts and returns the month number from the specified date-time value (Date data type).

Availability

This method is available in the following object models: Outlook, CDO, and ADO.

Syntax

Integer = atMonth(DateVal As Date)


atName

This method is not implemented. Calling it would raise a run-time error.


atNewLine

This method returns the Carriage Return + Line Feed characters.

Availability

This method is available in the following object models: Outlook, CDO, and ADO.

Syntax

String = atNewLine()

Usage Notes

This method returns whichever new line character is appropriate for the current platform.


atNo

This method returns the value False. This method is equivalent to the atFalse method.

Availability

This method is available in the following object models: Outlook, CDO, and ADO.

Syntax

Boolean = atNo()


atNoteID

This method returns a unique identifier for the current document. This method is equivalent to the atDocumentUniqueId method.

Availability

This method is available in the following object models: Outlook, CDO, and ADO.

Syntax

String = atNoteID()


atNow

This method returns the current date and time.

Availability

This method is available in the following object models: Outlook, CDO, and ADO.

Syntax

Date = atNow()


atOptimizeMailAddress

This method is not implemented. Calling it would raise a run-time error.


atPassword

This method is not implemented. Calling it would raise a run-time error.


atPi

This method returns pi (~ 3.1415927).

Availability

This method is available in the following object models: Outlook, CDO, and ADO.

Syntax

Double = atPi()


atPickList

This method is not implemented. Calling it would raise a run-time error.


atPlatform

This method is not implemented. Calling it would raise a run-time error.


atPostedCommand

This method is not implemented. Calling it would raise a run-time error.


atPower

This method returns the value of a number when raised to a specified exponent.

Availability

This method is available in the following object models: Outlook, CDO, and ADO.

Syntax

Double = atPower(Base As Double, Exponent As Double)


atPrompt

This method displays a modal dialog box to the user. It then returns a text value based on the user's actions in the dialog box.

Availability

This method is available in the following object models: Outlook and ADO.

Syntax

String = atPrompt(Style As String, [Title As String], [Prompt As String], [DefaultChoice], [ChoiceList], [FileType])


atProperCase

This method converts the given string to "proper" case. That is, the first letter of each word in the string is made uppercase while all other letters are made lowercase. For example, it would change the string "dOS" to "Dos". Compare the atLowerCase method.

Availability

This method is available in the following object models: Outlook, CDO, and ADO.

Syntax

String = atProperCase(StringToConvert As String)


atRandom

This method generates a random number between 0 and 1 (inclusive).

Availability

This method is available in the following object models: Outlook, CDO, and ADO.

Syntax

Single = atRandom()


atRefreshECL

This method is not implemented. Calling it would raise a run-time error.


REM

This method is not implemented. Calling it would raise a run-time error.


atRepeat

This method repeats a string a specified number of times subject to an optional maximum length.

Availability

This method is available in the following object models: Outlook, CDO, and ADO.

Syntax

String = atRepeat(StringToRepeat As String, NumberOfTimes As Long, [MaxCharacters])


atReplace

This method performs a find-and-replace operation on a string or array of strings. It performs the find-and-replace operation on the first element (a string or string array) in the SourceList before performing the same find-and-replace operation on the next element in the SourceList. It continues in this manner through all the elements in the SourceList. Compare atReplaceSubstring.

Availability

This method is available in the following object models: Outlook, CDO, and ADO.

Syntax

Variant = atReplace(SourceList, FindList, ReplaceList)

This method can return a string or a string array.


atReplaceSubstring

This method performs a find-and-replace operation on a string or array of strings. It performs the first find-and-replace operation on all the elements in the SourceList and then, similarly, performs the next find-and-replace operations on all the elements in the SourceList. It continues in this manner through all the find-and-replace operations, each time searching all the elements in the SourceList. Compare atReplace.

Availability

This method is available in the following object models: Outlook, CDO, and ADO.

Syntax

Variant = atReplaceSubstring(SourceList, FindList, ReplaceList)

This method can return a string or a string array.


atResponses

This method is not implemented. Calling it would raise a run-time error.


atReturn

This method is not implemented. Calling it would raise a run-time error.


atRight

This method searches a string and returns the rightmost characters in the string. If SearchParameter is a number n, then the result is the last n characters in the string; otherwise (if SearchParameter is a string), it returns all the characters to the right of the string.

The difference between this method and the atRightBack method is that atRight searches left to right while atRightBack searches right to left.

Availability

This method is available in the following object models: Outlook, CDO, and ADO.

Syntax

String = atRight(StringToLookIn As String, SearchParameter)


atRightBack

This method searches a string and returns the rightmost characters in the string. If SearchParameter is a number n, then the result is the last n characters in the string; otherwise (if SearchParameter is a string), it returns all the characters to the right of the string.

The difference between this method and the atRight method is that atRightBack searches right to left while atRight searches left to right.

Availability

This method is available in the following object models: Outlook, CDO, and ADO.

Syntax

String = atRightBack(StringToLookIn As String, SearchParameter)


atRound

This method rounds the given number (or array of numbers) to the nearest whole number. If you supply an additional number (the Factor parameter), it is used as the rounding factor.

Availability

This method is available in the following object models: Outlook, CDO, and ADO.

Syntax

Variant = atRound(NumberList, [Factor As Double = 1])

This method returns a number (Integer or Long data type) or an array of numbers.


atSecond

This method returns the seconds value from the specified date-time value (Date data type).

Availability

This method is available in the following object models: Outlook, CDO, and ADO.

Syntax

Integer = atSecond(TimeVal As Date)


atSelect

This method returns an item from a list of values based on the position in the list specified.

Availability

This method is available in the following object models: Outlook, CDO, and ADO.

Syntax

Variant = atSelect(Position As Long, ParamArray ListOfValues() As Variant)

This method returns a number (Integer or Long data type), a string, or an array, depending on the contents of the ListOfValues parameter.


SELECT

This method is not implemented. Calling it would raise a run-time error.


atSet

This method is not implemented. Calling it would raise a run-time error.


atSetDocField

This method sets the value of a specified field on an item with the specified EntryID.

Availability

This method is available in the following object models: Outlook, CDO, and ADO.

Syntax

Sub atSetDocField(EntryID As String, Field, Value)

Usage Notes

You can obtain the EntryID of the current document by calling the atDocumentUniqueId method.


atSetEnvironment

This method is not implemented. Calling it would raise a run-time error.


atSetField

This method sets the value of a specified field on the current item.

Availability

This method is available in the following object models: Outlook, CDO, and ADO.

Syntax

Sub atSetField(Field, Value)


atSign

This method indicates whether the value passed in the Number parameter is positive, negative, or zero.

Availability

This method is available in the following object models: Outlook, CDO, and ADO.

Syntax

Integer = atSign(Number As Double)


atSin

Given an angle in radians, this method returns the sine of the angle.

Availability

This method is available in the following object models: Outlook, CDO, and ADO.

Syntax

Double = atSin(Angle As Double)


atSoundex

This method is not implemented. Calling it would raise a run-time error.


atSqrt

This method returns the positive square root of the number specified with the Number parameter.

Availability

This method is available in the following object models: Outlook, CDO, and ADO.

Syntax

Double = atSqrt(Number As Double)


atSubset

This method searches a list (an array of values) and returns the number of values specified, counting from the beginning of the array if the Number parameter is positive, from the end of the array if Number is negative.

Availability

This method is available in the following object models: Outlook, CDO, and ADO.

Syntax

Variant = atSubset(ListOfValues, Number As Long)

This method returns a String, an array of numbers (Integer or Long data type), or an array of date-time values (Date data type).


atSuccess

This method returns the value True.

Availability

This method is available in the following object models: Outlook, CDO, and ADO.

Syntax

Boolean = atSuccess()


atSum

This method adds an array of numbers or number arrays and returns their sum.

Availability

This method is available in the following object models: Outlook, CDO, and ADO.

Syntax

Double = atSum(ParamArray NumberList() As Variant)

Usage Notes

If an element of the ParamArray array passed is itself a number array, all elements of that array are added as well.


atTan

Given an angle in radians, this method returns the tangent of the angle.

Availability

This method is available in the following object models: Outlook, CDO, and ADO.

Syntax

Double = atTan(Angle As Double)


atText

This method converts any value to a text string and optionally formats it, based on the parameters passed and the type of value to convert.

Availability

This method is available in the following object models: Outlook, CDO, and ADO.

Syntax

String = atText(ValueToProcess, [FormatString])


atTextToNumber

This method converts a text string to a number, where this is possible.

Availability

This method is available in the following object models: Outlook, CDO, and ADO.

Syntax

Double = atTextToNumber(StringToConvert As String)


atTextToTime

This method converts a text string to a date-time value (Date data type), where this is possible.

Availability

This method is available in the following object models: Outlook, CDO, and ADO.

Syntax

Date = atTextToTime(DateString As String)


atTime

This method translates numbers for the various components of time and date, and returns the time of day, using the Date data type.

Availability

This method is available in the following object models: Outlook, CDO, and ADO.

Syntax

Date = atTime(ParamArray ArgList() As Variant)


atToday

This method returns today's date.

Availability

This method is available in the following object models: Outlook, CDO, and ADO.

Syntax

Date = atToday()


atTomorrow

This method returns tomorrow's date.

Availability

This method is available in the following object models: Outlook, CDO, and ADO.

Syntax

Date = atTomorrow()


atTrim

This method removes redundant spaces from a string or array of strings, including leading and trailing spaces.

Availability

This method is available in the following object models: Outlook, CDO, and ADO.

Syntax

Variant = atTrim(TextList)

This method can return a string or a string array.


atTrue

This method returns the value True. This method is equivalent to the atYes method.

Availability

This method is available in the following object models: Outlook, CDO, and ADO.

Syntax

Boolean = atTrue()


atUnavailable

This method is not implemented. Calling it would raise a run-time error.


atUnique

This method removes duplicates from an array or, if the optional parameter is missing, returns a GUID.

Availability

This method is available in the following object models: Outlook, CDO, and ADO.

Syntax

String = atUnique([TextList])


atUpperCase

This method converts all characters in a string to uppercase. Compare with atProperCase and atLowerCase.

Availability

This method is available in the following object models: Outlook, CDO, and ADO.

Syntax

String = atUpperCase(StringToConvert As String)


atURLGetHeader

This method retrieves HTTP header information from the specified URL on the World Wide Web.

Availability

This method is available in the following object models: Outlook, CDO, and ADO.

Syntax

String = atURLGetHeader(URL As String, Header As String, [WebUserName As String], [WebPassword As String], [ProxyWebUserName], [ProxyWebPassword])

Usage Notes

In order to use this method you need the MSINET.OCX control, which is installed with Microsoft Visual Basic.


atURLHistory

This method is used for navigating through the history list of the Internet Explorer window that is activated by this class.

Availability

This method is available in the following object models: Outlook, CDO, and ADO.

Syntax

Sub atURLHistory(CommandText As String)


atURLOpen

This subroutine opens the specified URL.

Availability

This subroutine is available in the following object models: Outlook, CDO, and ADO.

Syntax

Sub atURLOpen([URL], [ReloadFlag As String], [CharSet], [WebUserName], [WebPassword], [ProxyWebUserName], [ProxyWebPassword])

Usage Notes

No UserName/Password parameters have been implemented. They are retained for compatibility with the syntax of Lotus Notes.


atUserAccess

This method is not implemented. Calling it would raise a run-time error.


atUserName

This method returns the currently logged-on user's name. It is not supported in ADO.

Availability

This method is available in the following object models: Outlook and CDO.

Syntax

String = atUserName()


atUserPrivileges

This method is not implemented. Calling it would raise a run-time error.


atUserRoles

This method is not implemented. Calling it would raise a run-time error.


atV2If

This method is not implemented. Calling it would raise a run-time error.


atV3UserName

This method returns the currently logged-on user's name. It is not supported in ADO.

Availability

This method is available in the following object models: Outlook and CDO.

Syntax

String = atV3UserName()


atVersion

This method returns the current version of Outlook or CDO. It is not supported for ADO.

Availability

This method is available in the following object models: Outlook and CDO.

Syntax

String = atVersion()


atViewTitle

This method returns the title of the currently selected view in Outlook. It is not supported in the other object models.

Availability

This method is available in the following object models: Outlook.

Syntax

String = atViewTitle()


atWeekday

This method returns the day of the week of the given date.

Availability

This method is available in the following object models: Outlook, CDO, and ADO.

Syntax

Integer = atWeekday(DateToProcess As Date)


atWord

This method returns the specified word from a string or a list of words from an array of strings.

Availability

This method is available in the following object models: Outlook, CDO, and ADO.

Syntax

Variant = atWord(TextList, Separator As String, WordNumber As Integer)

This method can return a string or a string array.


atYear

This method extracts and returns the year from the date specified in the DateVal parameter.

Availability

This method is available in the following object models: Outlook, CDO, and ADO.

Syntax

Integer = atYear(DateVal As Date)


atYes

This method returns the value True. This method is equivalent to the atTrue method.

Availability

This method is available in the following object models: Outlook, CDO, and ADO.

Syntax

Boolean = atYes()


atYesterday

This method returns yesterday's date.

Availability

This method is available in the following object models: Outlook, CDO, and ADO.

Syntax

Date = atYesterday()


atZone

This method returns time zone information about the current computer. The DateTime parameter is ignored.

Availability

This method is available in the following object models: Outlook, CDO, and ADO.

Syntax

Variant = atZone([DateTime As Date])

Time zone information is returned in the format n.d, where n = number of time zones from Greenwich and d = 1 if daylight savings time is in effect and d = 0 if it is not. For example, Pacific Daylight Time is indicated by "8.1".


Concat

This method concatenates two strings. It is used in conjunction with atImplode.

Availability

This method is available in the following object models: Outlook, CDO, and ADO.

Syntax

Variant = Concat(Param1, Param2)

This method can return a string or a string array.


CurrentItem

This property holds a reference to the Microsoft Outlook item from which the methods of this class are invoked.

Availability

This property is available in the following object models: Outlook, CDO, and ADO.

Based on the object model you are using, the type of object to which you assign this property will be an Outlook item, a CDO item, or an ADO record.

Syntax

Property CurrentItem As Object

© 2000-2001 Microsoft Corporation. All rights reserved.


Application Security Module Reference

This section contains reference information for programming with the Web Storage System Application Security Module.

Related Topics

  • Application Security Module

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Methods by Category

The following lists categorize Application Security Module methods by their functionality.

Category | Methods
Creating DACLs | DACL.CreateSecurityDACL
Protecting DACLs | DACL.SetProtected
Adding Entities | DACL.AddEntity DACL.AddEmptySecurityEntity DACL.AddSecurityEntity DACL.AddSimpleSecurityEntity
Getting Entities | DACL.GetAllByMask DACL.GetAllBySIDType DACL.GetEntityByIndex
Using Masks | DACL.CopyUserMasks DACL.GetAllByEqualMask DACL.GetAllByMask Entity.IsEqualMask Entity.IsEqualTo Entity.HasMask Entity.HasMaskByTemplate Entity.HasMaskOfEntity
Loading and Saving | DACL.Load DACL.Save DACL.SaveTo
Removing | DACL.RemoveByDisplayName DACL.RemoveByIndex DACL.RemoveByNT4Name DACL.RemoveBySID DACL.RemoveInheritedEntities
Searching | DACL.SearchForIndexByDisplayName DACL.SearchForIndexByMask DACL.SearchForIndexByNT4Name DACL.SearchForIndexBySID DACL.SearchForIndexBySIDType DACL.SearchForIndexForAnEqualMask DACL.SearchForObjectByDisplayName DACL.SearchForObjectByMask DACL.SearchForObjectByNT4Name DACL.SearchForObjectBySID DACL.SearchForObjectBySIDType DACL.SearchForObjectForAnEqualMask
Using Templates | DACL.ClearByTemplate DACL.MakeEqualToTemplate DACL.ModifyByTemplate DACL.SetByTemplate Entity.ClearByTemplate Entity.MakeEqualToTemplate Entity.SetByTemplate


Entity Object

An entity object is the programmatic instantiation of a user or group that can have access rights to an item in the Microsoft Web Storage System.

The HasMask method describes the logic for how bitwise evaluations are performed allow and deny rights.


DACL Object Methods

Platform SDK: Exchange 2000 Server

Methods

This section describes entity object methods.


ClearByTemplate Method

Clears from an entity object the masks of a specified entity in a DACL template.

objResult objEntity.ClearByTemplate(objDACLTemplate, strName);
objResult
An object that returns error codes and descriptions.
objDACLTemplate
A DACL object used as a template.
strName
A string value of an entity to match in the DACL template. This value can either be the domain and username of a user or group, or a predefined role such as an “Author.”
Example
var e = objDacl.SearchForObjectByNT4Name("MyDomain\\User1");
var objMapiRoles = DaclLegacyRoles();   //returns the predefined dacl with the mapi roles
objResult = e.ClearByTemplate(objMapiRoles, "owner");
if(FAILED(objResult.number)){
    //print the error message stored in  objResult.description
}

See Also

MakeEqualToTemplate Method

SetByTemplate Method

DACL Templates

© 2000-2001 Microsoft Corporation. All rights reserved.


HasMask Method

Determines if an entity object has specific rights to an item.

bool objEntity.HasMask(masks);
masks
A string value of bitmasks to compare with the entity object’s masks.
Remarks

This method returns TRUE if the masks for an entity object have the permissions specified by the masks parameter.

Masks in the Application Security Module have three parts: item mask, subcontainer mask, and subitem mask, and are specified from left to right. Each mask has an allow and deny bit. These bits pertain to a specific permission, such as read and write permissions.

Consider the masks in an entity object for a particular user:

[0x1, 0x2, 0x1, 0x2, 0x0, 0x0]

The following table describes the allow and deny bits for this user’s masks:

User: Item mask | User: Subcontainer mask | User: subitem mask
Allow: 0x1 Deny: 0x2 | Allow: 0x1 Deny: 0x2 | Allow: 0x0 Deny: 0x0

The binary evaluations for item and subcontainer masks are the same. The allow bit is 00000001 or 0x1, and the deny bit is 00000010 or 0x2.

Note that both allow and deny bits for the subitem mask are zeros which means that no check of those permissions is necessary.

Next we compare the user’s masks with masks that specify read permissions, TestRead, and masks that specify write permissions, TestWrite.

TestRead – [0x1, 0x1, 0x1, 0x1, 0x0, 0x0]

TestWrite – [0x2, 0x2, 0x2, 0x2, 0x0, 0x0]

The following table shows binary bitwise comparisons of the user’s masks with the TestRead and TestWrite masks for an item. For simplicity, the masks for subcontainers and subitems are not described in this detail.

Allow Bit for Item | Deny Bit for Item | Results
User: 00000001 TestRead: 00000001 | User: 00000010 TestRead: 00000001 | The allow bits match, thus the user has read permission for the item. The deny bits do not match, thus the user is not denied read rights.
User: 00000001 TestWrite: 00000010 | User: 00000010 TestWrite: 00000010 | The allow bits do not match, thus the user is not allowed write permission for the item. The deny bits do match, thus the user is denied write permission for the item.

These comparisons can be expressed programmatically as follows, where e is an entity object.

e.HasMask(TestRead) has one match, so this method returns TRUE.

e.HasMask(TestWrite) has no matches, so this method returns FALSE.

Note: All allow bits are evaluated first, then the deny bits are evaluated.

Example

var e = objDacl.SearchForObjectByNT4Name("MyDomain\\User1");
var m = new Array(0x0080, 0x0080, 0x0080, 0x0080, 0x0000, 0x0000);
if(e.HasMask(m)) {
    //user has that right
}

See Also

HasMaskByTemplate Method

HasMaskOfEntity Method

IsEqualMask Method

© 2000-2001 Microsoft Corporation. All rights reserved.


HasMaskByTemplate Method

Determines if an entity object has the masks of a specified entity in a DACL template object.

objResult objEntity.HasMaskByTemplate(strName, objDaclTemplate);
objResult
An object that returns error codes and descriptions.
strName
A string value of an entity to match in the DACL template. This value can either be the domain and username of a user or group, or a predefined role such as an “Author.”
ObjDaclTemplate
A DACL object used as a template to compare with the entity object.
Remarks

Returns TRUE if one or more masks in the entity object are matched with DACL template object.

This method is useful for determining if a user, the entity object, has a particular right—the masks of a specified entity.

Example
var e = objDacl.SearchForObjectByNT4Name("MYDOMAIN\\User1");
var objMapiRoles = DaclLegacyRoles();   //returns the predefined dacl with the mapi roles
if(e.HasMaskByTemplate("Owner", objMapiRoles)) {
    //user has that mapi role
}

See Also

HasMask Method

HasMaskOfEntity Method

IsEqualMask Method

DACL Templates

© 2000-2001 Microsoft Corporation. All rights reserved.


HasMaskOfEntity Method

Determines if an entity has the same mask as another entity.

objResult objEntity.HasMaskOfEntity(objEntity2);
objResult
An object that returns error codes and descriptions.
objEntity2
Another entity object used as a comparison.
Example
var e = objDacl.SearchForObjectByNT4Name("MyDomain\User1");
var objMapiRoles = DaclLegacyRoles();   //returns the predefined dacl with the mapi roles
var e2 = objMapiRoles.SearchForObjectByNT4Name("Owner");
if(e.HasMaskOfEntity(e2)) {
    //user has that mapi role
}

See Also

HasMask Method

HasMaskByTemplate Method

IsEqualMask Method

© 2000-2001 Microsoft Corporation. All rights reserved.


IsEqualMask Method

Determines if an entity object exactly contains the specified masks.

bool objEntity.IsEqualMask(masks);
masks
A string value of bitmasks to compare with the entity object.
Remarks

Returns TRUE if the bitmasks of the entity object exactly match the specified masks.

If a mask for an entity object is defined as 000101, the only specified mask that can return TRUE is 000101. The HasMask method, however, returns TRUE if it matches masks 000001, 000100 and 000101.

Example
var e = objDacl.SearchForObjectByNT4Name("MyDomain\User1");
var m = new Array(0x0080, 0x0080, 0x0080, 0x0080, 0x0000, 0x0000);
if(e.IsEqualMask(m)) {
    //user has that right
}

See Also

HasMask Method

HasMaskByTemplate Method

HasMaskOfEntity Method

© 2000-2001 Microsoft Corporation. All rights reserved.


IsEqualTo Method

Determines if two entity objects have the same masks.

bool objEntity.IsEqualTo(objEntity2);
objEntity2
An entity object whose masks are used as a comparison.
Example
var e = objDacl.SearchForObjectByNT4Name("MyDomain\User1");
var e2 = objDacl.SearchForObjectByNT4Name("MYDOMAIN\\joeweb")
if( false == e.IsEqualTo(e2) ){
   //these two users are not the same (as expected)
}


MakeEqualToTemplate Method

Sets the masks in an entity object equal to the masks of a specified entity in a DACL template object.

objResult objEntity.MakeEqualToTemplate(objDaclTemplate, strName);
objResult
An object that returns error codes and descriptions.
ObjDaclTemplate
A DACL object used as a template to compare with the entity object.
strName
A string value of an entity to match in the DACL template. This value can either be the domain and username of a user or group, or a predefined role such as an “Author.”
Example
var e = objDacl.SearchForObjectByNT4Name("MyDomain\User1");
var objMapiRoles = DaclLegacyRoles();   //returns the predefined dacl with the mapi roles
objResult = e.MakeEqualToTemplate("Owner", objMapiRoles);
if(FAILED(objResult.number)){
    //print the error message stored in  objResult.description
}

See Also

ClearByTemplate Method

SetByTemplate Method

DACL Templates

© 2000-2001 Microsoft Corporation. All rights reserved.


SetByTemplate Method

Adds masks to an entity object from a specified entity in a DACL template object.

objResult objEntity.SetByTemplate(objDACLTemplate, strName);
objResult
An object that returns error codes and descriptions.
objDACLTemplate
A DACL object used as a template.
strName
A string value of an entity to match in the DACL template. This value can either be the domain and username of a user or group, or a predefined role such as an “Author.”
Example
var e = objDacl.SearchForObjectByNT4Name("MyDomain\\User1");
var objMapiRoles = DaclLegacyRoles();   //returns the predefined dacl with the mapi roles
objResult = e.SetByTemplate(objMapiRoles, "Owner",);
if(FAILED(objResult.number)){
    //print the error message stored in objResult.description
}

See Also

ClearByTemplate Method

MakeEqualToTemplate Method

DACL Templates

© 2000-2001 Microsoft Corporation. All rights reserved.


DACL Object Properties

Platform SDK: Exchange 2000 Server

Properties

This section describes entity object properties.


DisplayName Property

Read-only. A display name for a security principal, such as an “Administrator,” that is derived from the Microsoft® Active Directory™.

string objEntity.DisplayName;
Example
Response.write(objEntity.DisplayName);


Inherited Property

A Boolean value specifying whether the security descriptor for an item is inherited from its parent folder.

bool objEntity.Inherited;
Example

FALSE

© 2000-2001 Microsoft Corporation. All rights reserved.


Masks Property

Read-only. The access masks for the Access Control Entry (ACE) expressed as a hexadecimal value.

string objEntity.Masks;
Example

1fc9ff

© 2000-2001 Microsoft Corporation. All rights reserved.


NT4Name Property

Read-only. A string value of the domain and username of a security principal.

string objEntity.NT4Name;
Example

\\TestDomainB12\User4

© 2000-2001 Microsoft Corporation. All rights reserved.


SID Property

Read-only. A security identifier.

string objEntity.SID;
Example

S-1-1-0

© 2000-2001 Microsoft Corporation. All rights reserved.


SIDType Property

Read-only. One of the following security identifier types: user, group, domain, alias, well_known_group, deleted_account, invalid, unknown, computer.

string objEntity.SIDType;
Example

user


DACL Object

The DACL object is an encapsulation the DACL security descriptor for a Web Storage System item, and contains a collection of entity objects.


Entity Object Methods

Platform SDK: Exchange 2000 Server

Methods

This section describes DACL object methods.


AddEmptySecurityEntity Method

Adds a new entity object with empty masks to a DACL object’s entity collection.

objResult objDACL.AddEmptyEntity(strSIDType, strSID, strNT4Name, strDisplayName [,bInherited]);
objResult
An object that returns error codes and descriptions.
strSIDType
A string value of one of the security identifier types as listed in the following table.
Security Identifier Type (SID)
user
group
domain
alias
well_known_group
deleted_account
invalid
unknown
computer

strSID
A string value of the name of the security identifier such as “S-1-1-0”.
strNT4Name
A string value of the domain and username of a security principal.
strDisplayName
A string value of the display name for the specified trustee such as an “Administrator.” This display name is derived from the Microsoft® Windows® 2000 Active Directory™ object for this trustee.
bInherited
Optional. A Boolean value to specify that the entity is inherited.
Remarks

This method creates a new entity with masks set to 0 and removes any duplicates.

You can use an empty string, “”, for the strSIDType parameter, however, a specified SID type results in improved performance in other DACL related function calls.

Example
var objResult = objDacl.AddEmptySecurityEntity("user", "S-1-1-10-…", "MyDomain\User1", "Joe T. User");
if( 1 == objResult.number) {
    //0 means user was added, no errors
    //1 means no error, but the user was not added –might be a duplicate
}

See Also

AddEntity Method

AddSimpleSecurityEntity Method

AddSecurityEntity Method

© 2000-2001 Microsoft Corporation. All rights reserved.


AddEntity Method

Adds a copy of an entity object to a DACL object’s entity collection.

objResult objDACL.AddEntity(objEntity);
objResult
An object that returns error codes and descriptions.
objEntity
An entity object to add to the DACL object.
Example
var e = objDacl2.SearchForObjectByNT4Name("MyDomain\\User1");
var objResult = objDacl.AddEntity(e);
if( 1 == objResult.number) {
    //0 means user was added, no errors
    //1 means no error, but the user was not added –maybe a duplicate
}

See Also

AddEmptySecurityEntity Method

AddSecurityEntity Method

AddSimpleSecurityEntity Method

© 2000-2001 Microsoft Corporation. All rights reserved.


AddSecurityEntity Method

This method adds a new entity object with specified masks to a DACL object’s entity collection.

objResult objDACL.AddSecurityEntity(strSIDType, strSID, strNT4Name, strDisplayName, masks [,bInherited]);
objResult
An object that returns error codes and descriptions.
strSIDType
A string value of one of the security identifier types as listed in the following table.
Security Identifier Type (SID)
user
group
domain
alias
well_known_group
deleted_account
invalid
unknown
computer

strSID
A string value of the name of the security identifier such as “S-1-1-0”.
strNT4Name
A string value of the domain and username of a security principal.
strDisplayName
The display name for the specified trustee such as an “Administrator.” This display name is derived from the Microsoft® Windows® 2000 Active Directory™ object for this trustee.
masks
An array of hexadecimal numbers; for example, [0x1fc9ff, 0x2, 0x12089, 0x0, 0x4, 0x0]. This number is the 32-bit access mask for the Access Control Entry (ACE).
bInherited
Optional. A Boolean value to specify that the entity is inherited.
Remarks

This method creates a new entity with masks set to 0 and removes any duplicates.

You can use an empty string, “”, for the strSID and strSIDType parameters however, a specified SID type results in improved performance in other DACL related function calls. Specifying the SID as an empty string causes the server to search for the SID.

Example
var objResult = objDacl.AddSecurityEntity("","","MYODMAIN\\JaneC", "Jane Clayton", [0x1fc9ff, 0x2, 0x12089, 0x0, 0x4, 0x0]);
if( 1 == objResult.number) {
    //0 means user was added, no errors
    //1 means no error, but the user was not added –maybe a duplicate
}

See Also

AddEmptySecurityEntity Method

AddEntity Method

AddSimpleSecurityEntity Method

© 2000-2001 Microsoft Corporation. All rights reserved.


AddSimpleSecurityEntity Method

This method adds a new entity object with no SID, SID type, or display name to a DACL object’s entity collection.

objResult objDACL.AddSimpleSecurityEntity(strNT4Name, masks);
objResult
An object that returns error codes and descriptions.
strNT4Name
A string value of the domain and username of a security principal.
masks
An array of hexadecimal numbers; for example, [0x1fc9ff, 0x2, 0x12089, 0x0, 0x4, 0x0]. This number is the 32-bit access mask for the Access Control Entry (ACE).
Example
var objResult = objDacl.AddSimpleSecurityEntity("MYODMAIN\\User1", [0x1fc9ff, 0x2, 0x12089, 0x0, 0x4, 0x0]);
if( 1 == objResult.number) {
    //0 means user was added, no errors
    //1 means no error, but the user was not added –maybe a duplicate
}

See Also

AddEmptySecurityEntity Method

AddEntity Method

AddSecurityEntity Method

© 2000-2001 Microsoft Corporation. All rights reserved.


ClearByTemplate Method

Clears from a DACL object the masks of a specified entity in a DACL template.

objResult objDACL.ClearByTempate(strName, objDACLTempate, strNT4NameinDACLTemplate);
objResult
An object that returns error codes and descriptions.
strName
A string value of an entity to match in the DACL template. This value can either be the domain and username of a user or group, or a predefined role such as an “Author.”
objDACLTemplate
A DACL object used as a template.
strNT4NameInDACLTemplate
A string value of the name of an entity in the DACL template object used to compare with the DACL object being evaluated.
Remarks

This method is a wrapper for ModifyByTemplate method, with predefined action parameter as “Clear.”

The following possible error messages can be returned:

  • Person not found.
  • Template entity not found.
Example
var objLRoles = DaclLegacyRoles();
var objErr = objDacl.ClearByTemplate("MyDomain\User1", objLRoles, "Reviewer");
if(FAILED(objErr.number)){
   //something went wrong
}

See Also

MakeEqualToTemplate Method

ModifyByTemplate Method

SetByTemplate Method

DACL Templates

© 2000-2001 Microsoft Corporation. All rights reserved.


CopyUserMasks Method

Copies the masks of one entity in a DACL object to another entity in the same DACL object.

objResult objDACL.CopyUserMasks(strName1, strName2);
objResult
An object that returns error codes and descriptions.
StrName1
A string value of the name of the entity in the DACL object whose masks are copied. This value can either be the domain and username of a user or group, or a predefined role such as an “Author.”
StrName2
A string value of the name of the entity in the DACL object that receives the copied masks. This value can either be the domain and username of a user or group, or a predefined role such as an “Editor.”
Example
var objErr = objDacl.CopyUserMasks("MyDomain\User1", "MYDOMAIN\\user2");
if(FAILED(objErr.number)){
   //something went wrong, couldn’t copy the masks
}


CreateSecurityDACL Method

Creates a DACL object from an item’s security descriptor.

objDACL CreateSecurityDACl([nLocation]);
objDACL
The created DACL object.
nLocation
Optional. Specifies whether to create the object on the server (default) or on the client. See the following table.
Constant | Value | Description
SECURITY_ON_SERVER() | 0 (default) | Creates the DACL object on the server using ADO to manipulate the security descriptor.
SECURITY_ON_CLIENT() | 1 | Creates the DACL object on the client using XMLHTTP to manipulate the security descriptor.

Remarks

This method returns a NULL value if it fails to create the object.

Example
var objDacl = CreateSecurityDACL(SECURITY_ON_SERVER());


GetAllByEqualMask Method

Returns an array of index values of entities in a DACL object that are equal to specified masks.

NdxArray[] objDACL.GetAllByEqualMask(masks);
NdxArray[]
An array of returned index values.
masks
An array of six hexadecimal values. Each mask is the access mask for the Access Control Entry (ACE).
Remarks

This method uses the IsEqualMask method to make comparisons.

Example
var ndxArray = objDacl.GetAllByEqualMask([0x810, 0x3A, 0x0, 0x0, 0x40, 0x0]);
if(ndxArray.length<1){
   //no one had those masks
}

See Also

GetAllByMask Method

© 2000-2001 Microsoft Corporation. All rights reserved.


GetAllByMask Method

Returns an array of index values of entities in a DACL object that match specified masks.

NdxArray[] objDACL.GetAllByMask(masks);
NdxArray[]
An array of returned index values.
masks
An array of six hexadecimal values. Each mask is the access mask for the Access Control Entry (ACE).
Remarks

This method uses the HasMask method to make comparisons.

Example
var ndxArray = objDacl.GetAllByMask([0x810, 0x3A, 0x0, 0x0, 0x40, 0x0]);
if(ndxArray.length<1){
   //no one had those masks
}

See Also

GetAllByEqualMask Method

© 2000-2001 Microsoft Corporation. All rights reserved.


GetAllBySIDType Method

Returns an array of index values of entities in a DACL object that match specified SID types.

NdxArray[] objDACL.GetAllBySIDType(masks);
NdxArray[]
An array of returned index values.
masks
An array of six hexadecimal values. Each mask is the access mask for the Access Control Entry (ACE).
Example
var ndxArray = objDacl.GetAllBySIDType([0x810, 0x3A, 0x0, 0x0, 0x40, 0x0]);
if(ndxArray.length<1){
   //no one had that sid
}

See Also

GetEntityByIndex Method

© 2000-2001 Microsoft Corporation. All rights reserved.


GetEntityByIndex Method

Returns an entity object by its index in the DACL object.

objEntity objDACL.GetEntityByIndex(nIndex);
objEntity
A returned entity object.
NIndex
An integer value of the index of the entity in the DACL object.
Remarks

This entity object collection is zero-based.

Example
var objEntity = objDacl.GetEntityByIndex(2);   //get the 3rd entity
if(null == objEntity){
   //no third entity
}

See Also

GetAllBySIDType Method

© 2000-2001 Microsoft Corporation. All rights reserved.


Load Method

Creates a DACL object by loading security descriptor information from a Web Storage System item.

objResult objDACL.Load(strURL [,strUser] [,strPwd]);
objResult
An object that returns error codes and descriptions.
strURL
A string value of the URL of the Web Storage System item for loading its security descriptor into a DACL object.
strUser
Optional. A string value of the username required for accessing the secured item.
strPwd
Optional. A string value of the password required for accessing the secured item.
Remarks

The username and password are optional because the current user’s authentication should already be established by enabling Integrated Authentication in Microsoft Internet Information Services (IIS).

Warning Storing usernames and passwords in script files poses a security risk.

Example
var objDacl = CreateSecurityDacl();
var objResult = objDacl.Load("http://server/folder/someitem");
if(FAILED(objResult.number)){
   //show an error msg here, using  objResult.description
}

See Also

Save Method

SaveTo Method

© 2000-2001 Microsoft Corporation. All rights reserved.


MakeEqualToTemplate Method

Sets the masks in a DACL object equal to the masks of a specified entity in a DACL template object.

objResult objDACL.MakeEqualToTemplate(strName, objDACLTempate, strNT4NameinDACLTemplate);
objResult
An object that returns error codes and descriptions.
strName
A string value of an entity to match in the DACL template. This value can either be the domain and username of a user or group, or a predefined role such as an “Author.”
objDACLTemplate
An DACL object used as a template.
strNT4NameInDACLTemplate
A string value of the name of an entity in the DACL template object used to compare with the DACL object being evaluated.
Remarks

This method is the same as the ModifyByTemplate method, except that the only action taken is to make the DACL object equal to the template.

  • The following possible error messages can be returned:
    • Person not found.
    • Template entity not found.
Example
var objLRoles = DaclLegacyRoles();
var objErr = objDacl.MakeEqualToTemplate("MYDOMAIN\\User1", objLRoles, "Reviewer");
if(FAILED(objErr.number)){
   //something went wrong, print err.description
}

See Also

ClearByTemplate Method

ModifyByTemplate Method

SetByTemplate Method

DACL Templates

© 2000-2001 Microsoft Corporation. All rights reserved.


ModifyByTemplate Method

Performs a specified action on any masks in a DACL object that match any masks of a specified entity in a DACL template object.

objResult objDACL.ModifyByTempate(strName, objDACLTempate, strNT4NameinDACLTemplate, strAction);
objResult
An object that returns error codes and descriptions.
strName
A string value of an entity to match in the DACL template. This value can either be the domain and username of a user or group, or a predefined role such as an “Author.”
objDACLTemplate
A DACL object used as a template.
strNT4NameInDACLTemplate
A string value of the name of an entity in the DACL template object used to compare with the DACL object being evaluated.
strAction
One of the actions described in the following table.
Action | Description of action taken
Make | Sets the masks of the DACL object equal to the template DACL object.
Set | Bit-wise OR the masks according to the template DACL object.
Clear | Bit-wise AND-NOT the masks according to the template DACL object.

Remarks

The following possible error messages can be returned:

  • Person not found.
  • Template entity not found.
  • Action parameter not recognized.
Example

The following example finds User1 in an objLRoles DACL template object and attempts to clear the reviewer permissions from User1’s masks. The "Reviewer" is an entity in the objLRoles object.

var objLRoles = DaclLegacyRoles();
var objErr = objDacl.ModifyByTemplate("MYDOMAIN\\User1", objLRoles, "Reviewer", "Clear");
if(FAILED(objErr.number)){
   //error handling code.
}

See Also

ClearByTemplate Method

MakeEqualToTemplate Method

SetByTemplate Method

DACL Templates

© 2000-2001 Microsoft Corporation. All rights reserved.


RemoveByDisplayName Method

Removes an entity object from a DACL object by using a display name to find the entity.

objResult objDACL.RemoveByDisplayName(strDisplayName);
objResult
An object that returns error codes and descriptions.
strDisplayName
A string value of the display name for a security principal such “Jane Clayton.”
Remarks

This method is not the most effective removal method because only the first matched entity would be removed if more than one entity had the same display name.

Example
var objErr = objDacl.RemoveByDisplayName("Jane Clayton");
if(FAILED(objErr.number)){
    //there was an error removing that user, print objErr.description
}

See Also

RemoveByIndex Method

RemovebyNT4Name Method

RemovebySID Method

© 2000-2001 Microsoft Corporation. All rights reserved.


RemoveByIndex Method

Removes an entity object from a DACL object by its index.

objResult objDACL.RemoveByIndex(nIndex);
objResult
An object that returns error codes and descriptions.
nIndex
An integer value of the index of the entity in the DACL object.
Remarks

Entity objects in a DACL are zero-based. The index for the first entity in the DACL is zero.

Example
var objErr = objDacl.RemoveByIndex(2);
if(FAILED(objErr.number)){
    //there was an error removing the third entity, print objErr.description
}

See Also

RemoveByIndex Method

RemovebyNT4Name Method

RemovebySID Method

© 2000-2001 Microsoft Corporation. All rights reserved.


RemoveByNT4Name Method

Removes an entity object from a DACL object by a domain and username.

objResult objDACL.RemoveByNT4Name(strDisplayName);
objResult
An object that returns error codes and descriptions.
strNT4Name
A string value of the domain and username of a security principal.
Remarks
var objErr = objDacl.RemoveByNT4Name("MYDOMAIN\\User1");
if(FAILED(objErr.number)){
    //there was an error removing that user, print objErr.description
}

See Also

RemoveByDisplayName Method

RemoveByIndex Method

RemovebySID Method

© 2000-2001 Microsoft Corporation. All rights reserved.


RemoveBySID Method

Removes an entity object from a DACL object by searching for a specific SID.

objResult objDACL.RemoveBySID(strSID);
objResult
An object that returns error codes and descriptions.
strSID
A string value of the name of the security identifier such as “S-1-1-0”.
Example
var objErr = objDacl.RemoveBySID("S-1-5-21-1343024091-1060284298-1417001333-1107");
if(FAILED(objErr.number)){
    //there was an error removing that user, print objErr.description
}

See Also

RemoveByDisplayName Method

RemoveByIndex Method

RemovebyNT4Name Method

© 2000-2001 Microsoft Corporation. All rights reserved.


RemoveInheritedEntries Method

Platform SDK: Exchange 2000 Server

RemoveInheritedEntities Method

Removes inherited entity objects from a DACL object.

objEntity objDACL.RemoveInheritedEntities();
objResult
An object that returns error codes and descriptions.
Remarks

This method finds and removes entities in the DACL object whose inherited attribute is TRUE.

Example
var objErr = objDacl.RemoveInheritedEntities();
if( 0 = objErr.number){
    //0 means no error, some inherited entities were removed
    //1 means no error, but no inherited entities were found to remove
}


Save Method

Saves DACL object data to its item’s security descriptor.

objResult objDACL.Save([strUsr [,strPwd]]);
objResult
An object that returns error codes and descriptions.
strUser
Optional. A string value of the username required for accessing the secured item.
strPwd
Optional. A string value of the password required for accessing the secured item.
Remarks

By design, this method does not save any inherited entities.

Warning Storing usernames and passwords in script files poses a security risk. If you write a script on a Web page that runs on a client for a browser other than Internet Explorer, the username and password will be passed in plain text to the UISaveDacl.asp file—a bigger security risk.

Example
var objResult = objDacl.Save();
if(FAILED(objResult.number)){
   //show an error msg here, using  objResult.description
}

See Also

Load Method

SaveTo Method

© 2000-2001 Microsoft Corporation. All rights reserved.


SaveTo Method

Saves DACL object information to the security descriptor of an item according to its URL.

objResult objDACL.SaveTo(strURL [,strUsr [,strPwd]]);
objResult
An object that returns error codes and descriptions.
strURL
The DACL object’s URL.
strUser
Optional. A string value of the username required for accessing the secured item.
strPwd
Optional. A string value of the password required for accessing the secured item.
Remarks

By design, this method does not save any inherited entities.

Warning Storing usernames and passwords in script files poses a security risk. If you write a script on a Web page that runs on a client for a browser other than Internet Explorer, the username and password will be passed in plain text to the UISaveDacl.asp file—a bigger security risk.

Example
var objResult = objDacl.SaveTo("http://server/folder/someitem");
if(FAILED(objResult.number)){
   //show an error msg here, using  objResult.description
}

See Also

Load Method

Save Method

© 2000-2001 Microsoft Corporation. All rights reserved.


SearchForIndexByDisplayName Method

Returns the index of an entity in a DACL object by a specified display name.

ndxEntity objDACL.SearchForIndexByDisplayName(strDisplayName);
ndxEntity
A long value of the entity’s index. This method returns a negative number if the entity is not found.
strDisplayName
A string value of the display name for the specified security principal such as “Jane Clayton.”
Remarks

This method is not the most effective search method because only the first matched entity would be found if more than one entity had the same display name.

Indexes are zero-based.

Example
var index = objDacl.SearchForIndexByDisplayName("Jane Clayton");
if(index<0){
    //user not found
}

See Also

SearchForIndexByMask Method

SearchForIndexBySID Method

SearchForIndexBySIDType Method

SearchForIndexForAnEqualMask Method

© 2000-2001 Microsoft Corporation. All rights reserved.


SearchForIndexByMask Method

Returns the index of an entity in a DACL object by specified masks.

ndxEntity objDACL.SearchForIndexByMask(masks);
ndxEntity
A long value of the entity’s index. This method returns a negative number if the entity is not found.
masks
An array of six hexadecimal values that represent the entity’s permissions.
Remarks

If there is more than one entity in the DACL with the same set of masks, this method only returns one object of the first matched set.

Indexes are zero-based.

Example

var index = objDacl.SearchForIndexByMask([0x810, 0x3A, 0x0, 0x0, 0x40, 0x0]);
if(index<0){
   //no one had those masks
}

See Also

SearchForIndexByDisplayNameMethod

SearchForIndexBySID Method

SearchForIndexBySIDType Method

SearchForIndexForAnEqualMask Method

© 2000-2001 Microsoft Corporation. All rights reserved.


SearchForIndexByNT4Name Method

Returns the index of an entity in a DACL object by the domain and username of a user or group.

ndxEntity objDACL.SearchForIndexByNT4Name(strNT4nanme);
ndxEntity
A long value of the entity’s index. This method returns a negative number if the entity is not found.
strNT4Name
A string value of the domain and username of a security principal, such as a user or group.
Remarks

Entity objects in a DACL are zero-based. The index for the first entity in the DACL is zero.

Example

var index = objDacl.SearchForIndexByNT4Name(“MyDomain\\User1”);
if(index<0){
    //user not found
}


SearchForIndexBySID Method

Returns the index of an entity in a DACL object by a specified SID.

ndxEntity objDACL.SearchForIndexBySID(strSID);
ndxEntity
A long value of the entity’s index. This method returns a negative number if the entity is not found.
strSID
A string value of the name of the security identifier such as “S-1-1-0”.
Remarks

If there is more than one entity in the DACL with the same SID, this method only returns one object of the first match.

Indexes are zero-based.

Example
var index = objDacl.SearchForIndexBySID("S-1-5-21-1343024091-1060284298-1417001333-1107");
if(index<0){
    //user not found
}

See Also

SearchForIndexByDisplayNameMethod

SearchForIndexByMask Method

SearchForIndexBySIDType Method

SearchForIndexForAnEqualMask Method

© 2000-2001 Microsoft Corporation. All rights reserved.


SearchForIndexBySIDType Method

Returns the index of an entity in a DACL object by a specified SID type.

ndxEntity objDACL.SearchForIndexBySIDType(strSIDType);
ndxEntity
A long value of the entity’s index. This method returns a negative number if the entity is not found.
strSIDType
A string value of one of the security identifier types as listed in the following table.
Security Identifier Type (SID)
user
group
domain
alias
well_known_group
deleted_account
invalid
unknown
computer

Remarks

If there is more than one entity in the DACL with the same SID Type attribute, this method only returns one object of the first match.

Indexes are zero-based.

Example
var index = objDacl.SearchForIndexBySIDType("group");
if(index<0){
   //no match = no groups
}

See Also

SearchForIndexByDisplayNameMethod

SearchForIndexByMask Method

SearchForIndexBySID Method

SearchForIndexForAnEqualMask Method

© 2000-2001 Microsoft Corporation. All rights reserved.


SearchForIndexForAnEqualMask Method

Returns the index of an entity in a DACL object whose masks are equal to specified masks.

ndxEntity objDACL.SearchForIndexForAnEqualMask(masks);
ndxEntity
A long value of the entity’s index. This method returns a negative number if the entity is not found.
masks
An array of one or more hexadecimal values. Each mask is the 32-bit access mask for the Access Control Entry (ACE).
Remarks

This method differs from SearchForObjectByMask in that only a set of masks that are equal in number to the specified masks will result in a match. This method calls the entity object’s IsEqualMask method.

If there is more than one entity in the DACL with an equal number of masks, this method only returns one object of the first matched set of masks.

Indexes are zero-based.

Example
ndxEntity index = objDacl.SearchForIndexForAnEqualMask([0x810, 0x3A, 0x0, 0x0, 0x40, 0x0]);
if(index<0){
   //no one had those masks
}

See Also

SearchForIndexByDisplayNameMethod

SearchForIndexByMask Method

SearchForIndexBySID Method

SearchForIndexBySIDType Method

© 2000-2001 Microsoft Corporation. All rights reserved.


SearchForObjectByDisplayName Method

Returns an entity object found by searching for a specified display name.

objEntity objDACL.SearchForObjectByDisplayName(strDisplayName)
objEntity
A returned entity object.
strDisplayName
A string value of the display name for the specified trustee such as “Jane Clayton.”
Remarks

This method is not the most effective search method because only the first matched entity would be found if more than one entity had the same display name.

Example
var objEntity = objDacl.SearchForObjectByDisplayName("Jane Clayton");
if(null == objEntity){
    //this user was not likely in the dacl
}

See Also

SearchForObjectByMask Method

SearchForObjectByNT4Name Method

SearchForObjectBySID Method

SearchForObjectBySIDType Method

SearchForObjectForAnEqualMask Method

© 2000-2001 Microsoft Corporation. All rights reserved.


SearchForObjectByMask Method

Returns an entity object found by searching for a specified masks.

objEntity objDACL.SearchForObjectByMask(masks)
objEntity
An entity object.
masks
An array of six hexadecimal values that represent the entity’s permissions.
Remarks

If there is more than one entity in the DACL with the same set of masks, this method only returns one object of the first matched set.

This method uses the HasMask method for searching.

Example
var objEntity = objDacl.SearchForObjectByMask([0x1, 0x2, 0x3, 0x4, 0x5, 0x6]);
if(null == objEntity){
    //no one had this mask
}

See Also

SearchForObjectByDisplayName Method

SearchForObjectByNT4Name Method

SearchForObjectBySID Method

SearchForObjectBySIDType Method

SearchForObjectForAnEqualMask Method

© 2000-2001 Microsoft Corporation. All rights reserved.


SearchForObjectByNT4Name Method

Returns an entity object found by searching for a Microsoft® Windows NT® Security Accounts Manager (SAM) compatible name, such as "MyDomain\User1".

objEntity objDACL.SearchForObjectByNT4Name(strNT4Name)
objEntity
A returned entity object.
strNT4Name
A string value of the domain and username of a security principal.
Example
var objEntity = objDacl.SearchForObjectByNT4Name("MYDOMAIN\\User1");
if(null == objEntity){
    //this user was not likely in the dacl
}

See Also

SearchForObjectByDisplayName Method

SearchForObjectByMask Method

SearchForObjectBySID Method

SearchForObjectBySIDType Method

SearchForObjectForAnEqualMask Method

© 2000-2001 Microsoft Corporation. All rights reserved.


SearchForObjectBySID Method

Returns an entity object found by searching for a specific SID.

objEntity objDACL.SearchForObjectBySID(strSID)
objEntity
A returned entity object.
strSID
A string value of the name of the security identifier such as “S-1-1-0”.
Example
var objEntity = objDacl.SearchForObjectBySID("S-1-5-21-1343024091-1060284298-1417001333-1107");
if(null == objEntity){
    //this user was not likely in the dacl
}

See Also

SearchForObjectByDisplayName Method

SearchForObjectByMask Method

SearchForObjectByNT4Name Method

SearchForObjectBySIDType Method

SearchForObjectForAnEqualMask Method

© 2000-2001 Microsoft Corporation. All rights reserved.


SearchForObjectBySIDType Method

Returns an entity object found by searching for a specified SID type.

objEntity objDACL.SearchForObjectBySIDType(strSIDType)
objEntity
A returned entity object.
strSIDType
A string value of one of the security identifier types as listed in the following table.
Security Identifier Type (SID)
user
group
domain
alias
well_known_group
deleted_account
invalid
unknown
computer

Remarks

If there is more than one entity in the DACL with the same SID Type attribute, this method only returns one object of the first matched entity.

Example
var objEntity = objDacl.SearchForObjectBySIDType("group");
if(null == objEntity){
    // since its null, no groups were in the dacl
}

See Also

SearchForObjectByDisplayName Method

SearchForObjectByMask Method

SearchForObjectByNT4Name Method

SearchForObjectBySID Method

SearchForObjectForAnEqualMask Method

© 2000-2001 Microsoft Corporation. All rights reserved.


SearchForObjectForAnEqualMask Method

Returns an entity object whose masks are equal to the specified masks.

objEntity objDACL.SearchForObjectForAnEqualMask(masks)
objEntity
A returned entity object.
Masks
An array of one or more hexadecimal values. Each mask is the 32-bit access mask for the Access Control Entry (ACE).
Remarks

This method differs from SearchForObjectByMask in that only a set of masks that are equal in number to the specified masks will result in a match. This method calls the entity object’s IsEqualMask method for searching.

If there is more than one entity in the DACL with an equal number of masks, this method only returns one object of the first matched set of masks.

Example
var objEntity = objDacl.SearchForObjectForAnEqualMask([0x1, 0x2, 0x3, 0x4, 0x5, 0x6]);
if(null == objEntity){
    //no one had this mask
}

See Also

SearchForObjectByDisplayName Method

SearchForObjectByMask Method

SearchForObjectByNT4Name Method

SearchForObjectBySID Method

SearchForObjectBySIDType Method

© 2000-2001 Microsoft Corporation. All rights reserved.


SetProtected Method

Protects a DACL object from inheriting any ACEs from a parent folder.

objDACL.SetProtected(boolflag);
boolflag
A Boolean value of either TRUE or FALSE.
Remarks

Specifying TRUE prevents the DACL from inheriting ACEs.

This method makes copies of the inherited entities, except for the ones that already have an explicit ACE. If there is already an explicit ACE, this method discards the inherited entity without making a copy. The method then removes all inherited entities.

To have a protected DACL not make copies of inherited entities, first remove all inherited entities by calling RemoveInheritedEntities, and then call SetProtected(TRUE).

Example
objDacl.SetProtected(true)

See Also

IsProtected Property

© 2000-2001 Microsoft Corporation. All rights reserved.


SetByTemplate Method

Provides the ability to bit-wise OR the masks of the DACL object, according to a specified DACL template name and entity name.

objResult objDACL.SetByTemplate(strNT4Name, objDACLTempate, strNT4NameinDACLTemplate);
objResult
An object that returns error codes and descriptions.
strNT4Name
A string value of the domain and username of a security principal.
objDACLTemplate
An DACL object used as a template.
strNT4NameInDACLTemplate
A string value of the name of an entity in the DACL template object used to compare with the DACL object being evaluated.
Remarks

This method is the same as the ModifyByTemplate method, except that the only action taken is to bit-wise OR the masks.

The following possible error messages can be returned:

  • Person not found.
  • Template entity not found.
Example
var objLRoles = DaclLegacyRoles();
var objErr = objDacl.SetByTemplate("MYDOMAIN\\User1", objLRoles, "Reviewer");
if(FAILED(objErr.number)){
   //something went wrong
}

See Also

ClearByTemplate Method

MakeEqualToTemplate Method

ModifyByTemplate Method

DACL Templates

© 2000-2001 Microsoft Corporation. All rights reserved.


Entity Object Properties

Platform SDK: Exchange 2000 Server

Properties

This section describes DACL object properties.


Count Property

Read-only. The number of entity objects in a DACL object.

int objDACL.Count;


Entities Property

Read-only. An array of entity objects that a DACL object contains.

string objDACL.Entities;


IsFolder Property

Read-only. A Boolean value specifying whether the DACL object’s URL is to an item that is a collection or a folder. If false, the item is not a collection of other items.

bool objDACL.Count;
Remarks

This property retrieves the value of the DAV:IsFolder property.


IsProtected Method

Platform SDK: Exchange 2000 Server

IsProtected Property

Returns TRUE if a DACL object does not inherit any ACEs from a parent folder.

bool objDACL.IsProtected()
objDACL
A DACL object.
Example
var bIsProtected  = objDacl.IsProtected()

See Also

SetProtected Method

© 2000-2001 Microsoft Corporation. All rights reserved.


Loc Property

Read-only. The location, server or client, where a DACL object is created. If 0, the DACL object was created on the server using ADO; if 1, the object was created on the client using an XMLHTTP object.

int objDACL.Loc;


URL Property

Read-only. The URL of the item from which a DACL object was obtained.

string objDACL.URL;


DACL Templates

The tables in this section describe templates of access masks you can use to compare with the masks of a user, group, or role. The Security.js file contains functions whose names are the names of these templates, and they return DACL objects containing the masks described in these tables.

To use DACL templates, use the template name for the objDACLTemplate parameter with the following methods:

DACL.MakeEqualToTemplate

DACL.SetByTemplate

DACL.ClearByTemplate

Entity.MakeEqualToTemplate

Entity.SetByTemplate

Entity.ClearByTemplate

Example

var e = objDacl.SearchForObjectByNT4Name("MYDOMAIN\\User1");
var objMapiRoles = DaclLegacyRoles();   //returns the DACL template with the mapi roles
if(e.HasMaskByTemplate("Owner", objMapiRoles)) {
    //user has that mapi role
}


DACLLegacyRoles Template

The following table lists MAPI roles and their masks as used in Microsoft® Exchange Server 5.5.

Role | Masks
None | [0x1208a9, 0xdc916, 0x1208a9, 0xdc916, 0x0, 0x1f0fbf]
Owner | [0x1fc9bf, 0x0, 0x1fc9bf, 0x0, 0x1f0fbf, 0x0]
Publishing Editor | [0x1208af, 0xdc910, 0x1208af, 0xdc910, 0x1f0fbf, 0x0]
Editor | [0x1208ab, 0xdc914, 0x1208ab, 0xdc914, 0x1f0fbf, 0x0]
Publishing Author | [0x1208af, 0xdc910, 0x1208af, 0xdc910, 0x120ea9, 0x1f0716]
Author | [0x1208ab, 0xdc914, 0x1208ab, 0xdc914, 0x120ea9, 0x1f0716]
Non-Editing Author | [0x1208ab, 0xdc914, 0x1208ab, 0xdc914, 0x120ca9, 0x1f0716]
Reviewer | [0x1208a9, 0xdc916, 0x1208a9, 0xdc916, 0x1208a9, 0x1f0716]
Contributor | [0x1208ab, 0xdc914, 0x1208ab, 0xdc914, 0x0, 0x1f0fbf]


DACLLegacyMetaRights Template

The following table lists MAPI permissions and their masks as used in Microsoft® Exchange Server 5.5.

Permission | Masks
Create items | [0x000002, 0x000002, 0x000002, 0x000002, 0x000000, 0x0000]
Read items | [0x000001, 0x000001, 0x000001, 0x000001, 0x1208a9, 0x08a9]
Create subfolders | [0x000004, 0x000004, 0x000004, 0x000004, 0x000000, 0x0000]
Folder owner | [0x0d4110, 0x0d4910, 0x0d4110, 0x0d4910, 0x000000, 0x0000]
Folder contact | [0x008000, 0x008000, 0x008000, 0x008000, 0x000000, 0x0000]
Folder visible | [0x1208A8, 0x1200A8, 0x1208A8, 0x1200A8, 0x000000, 0x0000]
Edit none | [0x0, 0x0, 0x0, 0x0, 0x0, 0x0]
Edit own | [0x0, 0x0, 0x0, 0x0, 0x00200, 0x00000]
Edit all | [0x0, 0x0, 0x0, 0x0, 0xC0116, 0x1E0316]
Delete none | [0x0, 0x0, 0x0, 0x0, 0x0, 0x0]
Delete own | [0x0, 0x0, 0x0, 0x0, 0x00400, 0x0]
Delete all | [0x0, 0x0, 0x0, 0x0, 0x10000, 0x10400]


DACLWebStorageItem Template

The following table lists permissions and their masks for working with Web Storage System items.

Permission | Masks
Read body | [0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001]
Write body | [0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002]
Read properties | [0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008]
Write properties | [0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010]
Read attributes | [0x0080, 0x0080, 0x0080, 0x0080, 0x0080, 0x0080]
Write attributes | [0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100]
Write owned objects | [0x0200, 0x0200, 0x0200, 0x0200, 0x0200, 0x0200]
Delete owned objects | [0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400]
View item | [0x0800, 0x0800, 0x0800, 0x0800, 0x0800, 0x0800]
Delete | [0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000]
Read Permissions | [0x20000, 0x20000, 0x20000, 0x20000, 0x20000, 0x20000]
Write Permissions | [0x40000, 0x40000, 0x40000, 0x40000, 0x40000, 0x40000]
Write owner | [0x80000, 0x80000, 0x80000, 0x80000, 0x80000, 0x80000]
Synchronize | [0x100000, 0x100000, 0x100000, 0x100000, 0x100000, 0x100000]


DACLWebStorageFolder Template

The following table lists permissions and their masks for working with Web Storage System folders.

Permission | Masks
Folder List contents | [0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001]
Folder Create item | [0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002]
Folder Create container | [0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004]
Folder Read properties | [0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008]
Folder Write properties | [0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010]
Folder Read attributes | [0x0080, 0x0080, 0x0080, 0x0080, 0x0080, 0x0080]
Folder Write attributes | [0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100]
Folder Owner | [0x4000, 0x4000, 0x4000, 0x4000, 0x4000, 0x4000]
Folder Contact | [0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000]
Folder Delete | [0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000]
Folder Read Permissions | [0x20000, 0x20000, 0x20000, 0x20000, 0x20000, 0x20000]
Folder Write Permissions | [0x40000, 0x40000, 0x40000, 0x40000, 0x40000, 0x40000]
Folder Write owner | [0x80000, 0x80000, 0x80000, 0x80000, 0x80000, 0x80000]
Synchronize | [0x100000, 0x100000, 0x100000, 0x100000, 0x100000, 0x100000]


DACLNTFile Template

The following table lists permissions and their masks for files on a Microsoft® Windows® file system, and is provided here only as a reference for comparing with Web Storage System items.

Permissions | Masks
Read Data | [0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001]
Write Data | [0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002]
Append Data | [0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004]
Read Extended Attributes | [0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008]
Write Extended Attributes | [0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010]
Execute File | [0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020]
Read Attributes | [0x0080, 0x0080, 0x0080, 0x0080, 0x0080, 0x0080]
Write Attributes | [0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100]
Delete | [0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000]
Read Permissions | [0x20000, 0x20000, 0x20000, 0x20000, 0x20000, 0x20000]
Write Permissions | [0x40000, 0x40000, 0x40000, 0x40000, 0x40000, 0x40000]
Take Ownership | [0x80000, 0x80000, 0x80000, 0x80000, 0x80000, 0x80000]
Synchronize | [0x100000, 0x100000, 0x100000, 0x100000, 0x100000, 0x100000]


DACLNTFolder Template

The following table lists permissions and their masks for folders on a Microsoft® Windows® file system, and is provided here only as a reference for comparing with Web Storage System folders.

Permission | Masks
List Folder | [0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001]
Create File | [0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002]
Create Folders | [0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004]
Read Extended Attributes | [0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008]
Write Extended Attributes | [0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010]
Traverse Folder | [0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020]
Read Attributes | [0x0080, 0x0080, 0x0080, 0x0080, 0x0080, 0x0080]
Write Attributes | [0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100]
Delete | [0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000]
Read Permissions | [0x20000, 0x20000, 0x20000, 0x20000, 0x20000, 0x20000]
Write Permissions | [0x40000, 0x40000, 0x40000, 0x40000, 0x40000, 0x40000]
Take Ownership | [0x80000, 0x80000, 0x80000, 0x80000, 0x80000, 0x80000]
Synchronize | [0x100000, 0x100000, 0x100000, 0x100000, 0x100000, 0x100000]


Global Functions

The Application Security Module provides the following global functions.

Function Description Example
NumMasks() Returns the number of masks defined in an entity object.
var n = NumMasks();
FAILED(nNum) Determines if a call failed. Similar to the FAILED(hr) in C/C++.
If FAILED(objResult.number){  //error handling code

}
SUCCEEDED(nNum) Determines if a call succeeded. Similar to SUCCEEDED(hr) in C/C++.
If SUCCEEDED(objResult.number){  //error handling code

}
objDacl DaclLegacyRoles() Returns predefined permissions that represent the MAPI roles defined for a MAPI top-level hierarchy folder, as accessed by the Exchange System Manager. var ObjDaclLRoles = DaclLegacyRoles();

// ObjDaclLRoles can now be used with some other DACL wherever a “template” is needed.
objDacl DaclLegacyMetaRights() Similar to the DaclLegacyRoles function. Returns permissions such as “Can Create Subfolders.” var ObjDaclLMetaRights = DaclLegacyMetaRights();

// ObjDaclLMetaRights can now be used with some other DACL wherever a “template” is needed.
objDacl DaclWebStorageItem() Returns permissions for a Web Storage System item. var ObjDaclWebStorageItem = DaclWebStorageItem();

// ObjDaclWebStorageItem can now be used with some other DACL wherever a “template” is needed.
objDacl DaclWebStorageFolder() Returns permissions for a Web Storage System folder. var ObjDaclWebStorageFolder = DaclWebStorageFolder();

// ObjDaclWebStorageFolder can now be used with some other DACL wherever a “template” is needed.
objDacl DaclNTFile() Returns the permissions for an item in the Microsoft® Windows® file system. These permissions are not used by the Application Security Module, but are available as a reference. var ObjDaclNTFile = DaclNTFile();

// ObjDaclNTFile can now be used with some other DACL wherever a “template” is needed.
objDacl DaclNTFolder() Returns the permissions for a folder in the Microsoft® Windows® file system. These permissions are not used by the Application Security Module, but are available as a reference. var ObjDaclNTFolder = DaclNTFolder();

// ObjDaclNTFolder can now be used with some other DACL wherever a “template” is needed.


Error Handing Function

Many of the Application Security methods return an error object by using the CreateSecurityError function in the Security.js file as shown here. This object is referred to in this documentation as the objResult object.

function CreateSecurityError(nNumber, strDescription)
{
   var   error = new Object;

   if (typeof(nNumber) == "undefined")
      error.number = 0;
   else{
       error.number = MakeNegativeLong(nNumber);
   }

   if (typeof(strDescription) == "undefined")
      error.description = "No error";
   else
      error.description = strDescription;

   return error;
}


Packaging and Deployment

This section describes the Application Programming Interface (API) for programmatically packaging and deploying Microsoft Web Storage System applications as performed by the Application Deployment Wizard.

CLSID

A9DE381D-F68A-4CF5-BE55-5B5F55D2FF41

ProgID

ExInstaller.ExAppInstaller.1

Type Library

ExInstaller 2.0 Type Library

Location and Filename

\Program Files\Web Storage System\Tools\AppDeployWiz\Exinstaller.dll

Implemented Interfaces
  • IExAppInstallerEx—This interface is an extension of the older IExAppInstaller interface, containing more options for packaging and deploying applications.
  • IExAppInstaller—This interface is superceded by the IExAppInstaller interface and is not documented.

See Also

Web Storage System Application Deployment Wizard


IExAppInstallerEx Interface

This interface contains the following methods:

Method | Description
InstallApp | This method is superceded by the InstallAppEx method and is not documented.
InstallAppEx | This method installs a packaged application.
InstallAppFromURL | This method installs a CAB file from a Web URL.
PackFolder | This method is superceded by the PackFolderEx method and is not documented.
PackFolderEx | This method packages an application.


InstallAppEx Method

Installs an application from a CAB file or a folder.

[Visual Basic]
Sub InstallAppEx(ByVal bstrDstFolderURL As String, ByVal bstrSrcFileFullPath As String, ByVal bstrUserName As String, ByVal bstrPassword As String, ByVal lFileOption As Long, ByVal lOverwriteOption As Long, ByVal hInstall As Long, ByVal lTotalTicks As Long)
[C++]
HRESULT InstallAppEx(BSTR bstrDstFolderURL,
                     BSTR bstrSrcFileFullPath,
                     BSTR bstrUserName,
                     BSTR bstrPassword,
                     long lFileOption,
                     long lOverwriteOption,
                     long hInstall,
                     long lTotalTicks);
[IDL]
HRESULT InstallAppEx(
                [in] BSTR bstrDstFolderURL,
                [in] BSTR bstrSrcFileFullPath,
                [in] BSTR bstrUserName,
                [in] BSTR bstrPassword,
                [in] long lFileOption,
                [in] long lOverwriteOption,
                [in] long hInstall,
                [in] long lTotalTicks);

Parameters

bstrDstFolderURL
The URL to the destination Web Storage System folder where the application is to be installed. The folder and any of its parent folders that do not exist will be created.
bstrSrcFileFullPath
The absolute path in the Microsoft® Windows® file system of the packaged application. This can either be the path and filename for a CAB file, or the path to a folder of a packaged application.
bstrUserName
The username required for authentication.
bstrPassword
The password required for authentication.
lFileOption
Specify 0 to install from a CAB file or 1 from a folder.
lOverwriteOption
Controls overwrite options if a CAB file or folder exists. Specify 0 to prompt a confirmation, 1 to fail, or 2 to overwrite without a confirmation.
hInstall
Reserved. Specify 0 (zero).
lTotalTicks
Reserved. Specify 0 (zero).

Remarks

This method is an extension of the older InstallApp method that provided installation from a CAB file and not from a folder.

Example

Visual Basic

Dim obj As New ExAppInstaller

obj.InstallAppEx bstrTargetURL, _

bstrCabFile, _

bstrName, bstrPassword, _

1, 2, 0, 0

C++

      IExAppInstallerPtr spObject;
      hr = spObject.CreateInstance(__uuidof(ExAppInstaller));
      if (FAILED(hr)) {
         // error handling code...
      }

      hr = spObject->InstallAppEx(
         bstrFolderURL,
         bstrPackageName,
         bstrUserName,
         bstrPassword,
         1,2,0,0
         );
      if (FAILED(hr) ) {
         // error handling code...
      }


InstallAppFromURL Method

Installs an application from a Web URL either inside or outside the Web Storage System. This method only installs CAB files.

[Visual Basic]
Sub InstallAppFromURL(ByVal bstrSrcURL As String, ByVal bstrSrcUserName As String, ByVal bstrSrcPassword As String, ByVal bstrDstFolderURL As String, ByVal bstrDstUserName As String, ByVal bstrDstPassword As String, ByVal lFileOption As Long, ByVal lOverwriteOption As Long, ByVal hInstall As Long, ByVal lTotalTicks As Long)
[C++]
HRESULT InstallAppFromURL(BSTR bstrSrcURL,
                          BSTR bstrSrcUserName,
                          BSTR bstrSrcPassword,
                          BSTR bstrDstFolderURL,
                          BSTR bstrDstUserName,
                          BSTR bstrDstPassword,
                          long lFileOption,
                          long lOverwriteOption,
                          long hInstall,
                          long lTotalTicks);
[IDL]
HRESULT InstallAppFromURL(
                [in] BSTR bstrSrcURL,
                [in] BSTR bstrSrcUserName,
                [in] BSTR bstrSrcPassword,
                [in] BSTR bstrDstFolderURL,
                [in] BSTR bstrDstUserName,
                [in] BSTR bstrDstPassword,
                [in] long lFileOption,
                [in] long lOverwriteOption,
                [in] long hInstall,
                [in] long lTotalTicks);

Parameters

bstrSrcURL
The URL to the CAB file.
bstrSrcUserName
The username required for authentication to the source URL.
bstrSrcPassword
The password required for authentication to the source URL.
bstrDstFolderURL
The URL to the destination Web Storage System folder where the application is to be installed. The folder, and any of its parent folders, that do not exist will be created.
bstrDstUserName
The username required for authentication to the destination URL.
bstrDstPassword
The password required for authentication to the destination URL.
lFileOption
Specify 0 to install from a CAB file or 1 from a folder.
lOverwriteOption
Controls overwrite options if a CAB file or folder exists. Specify 0 to prompt a confirmation, 1 to fail, or 2 to overwrite without a confirmation.
hInstall
Reserved. Specify 0 (zero).
lTotalTicks
Reserved. Specify 0 (zero).

Example

Visual Basic

Dim obj As New ExAppInstaller

obj.InstallAppFromURL bstrSrcURL, _

bstrSrcUserName, _

bstrSrcPassword, _

bstrDstFolderURL, _

bstrDstUserName, _

bstrDstPassword, _

1, 2, 0, 0

C++

      IExAppInstallerPtr spObject;
      hr = spObject.CreateInstance(__uuidof(ExAppInstaller));
      if (FAILED(hr)) {
         // error handling code...
      }

      hr = spObject->InstallAppFromURL(
        btrSrcUserName,
        bstrSrcPassword,
        bstrDstFolderURL,
        bstrDstUserName,
        bstrDstPassword,
         1,2,0,0
         );
      if (FAILED(hr) ) {
         // error handling code...
      }


PackFolderEx Method

Packages an application to either a CAB file or a folder.

[Visual Basic]
Sub PackFolderEx(ByVal bstrSrcFolderURL As String, ByVal bstrPackageFullPath As String, ByVal fIncludeSubFolders As Boolean, ByVal bstrSchemaFilterFile As String, ByVal bstrUserName As String, ByVal bstrPassword As String, ByVal lFileOption As Long, ByVal lOverwriteOption As Long, ByVal pfnCallBack As Long)
[C++]
HRESULT InstallAppEx(BSTR bstrSrcFolderURL,
                     BSTR bstrPackageFullPath,
                     VARIANT_BOOL fIncludeSubFolders,
                     BSTR bstrSchemaFilterFile,
                     BSTR bstrUserName,
                     BSTR bstrPassword,
                     long lFileOption,
                     long lOverwriteOption,
                     long pfnCallBack);
 [IDL]
HRESULT InstallAppEx(
                [in] BSTR bstrSrcFolderURL,
                [in] BSTR bstrPackageFullPath,
                [in] VARIANT_BOOL fIncludeSubFolders,
                [in] BSTR bstrSchemaFilterFile,
                [in] BSTR bstrUserName,
                [in] BSTR bstrPassword,
                [in] long lFileOption,
                [in] long lOverwriteOption,
                [in] long pfnCallBack);

Parameters

bstrSrcFolderURL
The URL to the Web Storage System folder of the application to be packaged.
bstrPackageFullPath
The absolute path and filename for the packaged application on the Microsoft Windows file system. This parameter can either to a CAB file or a folder containing the application’s contents.
fIncludeSubFolders
If TRUE, instructs the installer to of the application’s subfolders in the package.
bstrSchemaFilterFile
A schema file to include or exclude properties and to fix items with the correct URLs. The default file provided by the Application Deployment Wizard is \Program Files\Exchsrvr\Tools\AppDeployWiz\samplefilter.xml. This file excludes such properties as DAV:parentname that would have no relevance in packaging an application. For Tahoe, this file is in the \Program Files\Web Storage System\Tools\AppDeployWiz folder.
bstrUserName
The username required for authentication.
bstrPassword
The password required for authentication.
lFileOption
Specify 0 to package the application in a CAB file or 1 to package the application in a folder.
lOverwriteOption
Controls overwrite options if a CAB file or folder exists. Specify 0 to prompt a confirmation, 1 to fail, or 2 to overwrite without a confirmation.
pfnCallBack
Reserved. Specify 0 (zero).

Remarks

This method is an extension of the folder PackageApp method that provided packaging for the application in a CAB file and not in a folder.

Example

Visual Basic

  Dim obj As New ExAppInstaller
  obj.PackFolderEx bstrAppURL, _
                 bstrCabFile, _
                 fIncludeAllSubFolders, _
                 bstrSchemaFilterFile, _
                 bstrName, bstrPassword, _
                 0,2,0

C++

      IExAppInstallerPtr spObject;
      hr = spObject.CreateInstance(__uuidof(ExAppInstaller));
      if (FAILED(hr)) {
         // error handling code...
      }

      hr = spObject->PackFolderEx(
         bstrAppURL,
         bstrPackageName,
         fIncludeSubfolders,
         bstrSchemaFilterFile,
         bstrUserName,
         bstrPassword,
         0,2,0 );
      if (FAILED(hr)) {
         // error handling code...
      }


Collaboration Data Objects

The following sections describe the objects to use when working with CDO for Exchange 2000 Server (CDOEX), CDO for Exchange Management (CDOEXM), and Collaboration Data Objects Workflow (CDOWF).

Object Models

COM Classes

Interfaces

Enumerations

Schema Properties

Error Codes

WMI Classes

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Object Models

The following topics illustrate the object models for CDO for Exchange 2000 Server (CDOEX), CDO for Exchange Management (CDOEXM), and Collaboration Data Objects Workflow (CDOWF).

CDO for Exchange 2000 Server Objects

CDO for Exchange Management Objects

CDO for Workflow Objects

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


CDO for Exchange 2000 Server Objects


CDO for Exchange Management Objects


CDO for Workflow Objects


COM Classes

The topics in this section describe the Component Object Model (COM) classes for CDO for Exchange 2000 Server (CDOEX), CDO for Exchange Management (CDOEXM), and Collaboration Data Objects Workflow (CDOWF).

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Addressee CoClass

Provides address resolution for recipients of messages and meeting requests; also provides access to free/busy information for attendees of meetings.

CLSID
CD000110-8B95-11D1-82DB-00C04FB1625D
ProgID
CDO.Addressee
Type Library
Microsoft® CDO for Microsoft Exchange Library
Inproc Server
CDOEX.DLL
Threading Model
Both

Implemented Interfaces

IAddressee

OLE DB Row Access

Remarks

Names and addresses in the Addressee objects are resolved against a list of LDAP servers or contact folder URLs, as listed by the Configuration object. Default LDAP URLs can be read from the account information in Microsoft Outlook® Express.

Example

The following example uses an Addressee object to get the free/busy status of user12. It uses the LDAP protocol to get directory information from the exsvr3 server.

[Visual Basic]
Dim iAddr    As New CDO.Addressee
Dim freebusy As     String

iAddr.EmailAddress = "user12@exchange.microsoft.com"
iAddr.CheckName ("LDAP://exsvr3")

'get free/busy status in 30 minute intervals from 9:00 am to 5:00 pm
freebusy = iAddr.GetFreeBusy(#7/8/1999 9:00:00 AM#, #7/8/1999 5:00:00 PM#, 30)
Debug.Print (freebusy)


Appointment CoClass

Defines appointments, and provides methods and properties for sending, responding to, and managing them.

CLSID
CD000100-8B95-11D1-82DB-00C04FB1625D
ProgID
CDO.Appointment
Type Library
Microsoft® CDO for Microsoft Exchange Library
Inproc Server
CDOEX.DLL
Threading Model
Both

Implemented Interfaces

IAppointment

IBodyPart

IDataSource

OLE DB Row Access

Supported IDataSource Bindings

IDataSource method | Target argument | Content class
Open | Microsoft Web Storage System item URL | urn:content-classes:appointment
OpenObject | IRow _Record IStream _Stream IBodyPart | urn:content-classes:appointment
SaveTo | Web Storage System item URL | N/A
SaveToContainer | Web Storage System folder URL | N/A
SaveToObject | IRow _Record IStream _Stream IBodyPart | N/A

Remarks

The IAppointment interface is used for creating appointments and for sending and responding to meeting requests. It contains methods that create a CalendarMessage object for encapsulating meeting requests and responses as a message. The CalendarMessage object provides access to the IMessage interface for Send and other methods. It also provides access to the ICalendarParts interface, which filters a message for body parts containing calendar content.

The IDataSource interface facilitates opening data from and saving data to other objects. The IBodyPart interface acts as the root of the hierarchy of MIME body parts in the message.

You can also use the Appointment object's GetNextInstance and GetFirstInstance methods to examine a recurring appointment. Use the Publish method to send an announcement of the meeting to recipients who need not respond.

Example

[Visual Basic]
Function CreateAndSendMeeting(iMbx As CDO.IMailbox) As CDO.Appointment
  Dim iAppt      As New Appointment
  Dim Config     As New Configuration
  Dim iCalMsg    As CalendarMessage
  Dim iAttn1     As Attendee
  Dim iMsg       As CDO.Message

  'Set the configuration fields
  Config.Fields("CalendarLocation") = iMbx.Calendar
  Config.Fields(cdoSendEmailAddress) = "meetingorganizer@microsoft.com"
  Config.Fields.Update

  With iAppt
    Set .Configuration = Config

    'Set the appointment properties
    .StartTime = #8/20/1999 10:00:00 AM#
    .EndTime = #8/20/1999 11:30:00 AM#
    .Subject = "Department meeting"
    .Location = "Executive Conference Room"

    'Add a required attendee
    Set iAttn = .Attendees.Add
    iAttn.Address = "MAILTO:someone@microsoft.com"
    iAttn.Role = cdoRequiredParticipant

    'Add an optional attendee
    Set iAttn = .Attendees.Add
    iAttn.Address = "MAILTO:another@microsoft.com"
    iAttn.Role = cdoOptionalParticipant

    'Create the calendar message and send it
    Set iCalMsg = .CreateRequest
    Set iMsg = iCalMsg.Message
    iMsg.Send

    'Save the meeting to the organizer's calendar
    .Datasource.SaveToContainer iMbx.Calendar

   End With

   Set CreateAndSendMeeting = iAppt

End Function
© 2000-2001 Microsoft Corporation. All rights reserved.


Attendee CoClass

Specifies the attendees of an appointment and the recipients of a meeting request.

CLSID
CD00010D-8B95-11D1-82DB-00C04FB1625D
ProgID
CDO.Attendee
Type Library
Microsoft® CDO for Microsoft Exchange Library
Inproc Server
CDOEX.DLL
Threading Model
Both

Implemented Interfaces

IAttendee

OLE DB Row Access

Supported IDataSource Bindings

None

Remarks

An Attendee object represents an individual attendee that is contained within the Attendees collection. An Attendee object contains a set of properties used to specify the attendee and to keep track of the attendee's role and status.

Example

[Visual Basic]
Dim iAppt As New Appointment
Dim iAttendee As New Attendee
'Add an attendee
Set iAttendee = iAppt.Attendees.Add
iAttendee.Address = "someone@microsoft.com"
iAttendee.Role = cdoRequiredParticipant


Attendees CoClass

Defines an object used to manage a collection of Attendee objects.

CLSID
Not applicable
ProgID
Not applicable
Type Library
Microsoft® CDO for Microsoft Exchange Library
Inproc Server
CDOEX.DLL
Threading Model
Both

Implemented Interfaces

IAttendees

Supported IDataSource Bindings

None

Example

The following example opens the first appointment in a user's calendar. The example then uses an Attendees object to list each attendee for the appointment.

Note This example uses a file URL with the Exchange OLE DB (ExOLEDB) provider. The ExOLEDB provider also supports the HTTP URL scheme.

[Visual Basic]
Dim IAtnds      As     IAttendees
Dim IAtnd       As     Attendee
Dim IAppt       As New Appointment
Dim Rs          As New ADODB.Recordset
Dim Rec         As New ADODB.Record
Dim CalendarURL As     String
Dim ItemURL     As     String
Dim Index       As     Integer

CalendarURL = "file://./backofficestorage/exchange.microsoft.com/MBX/user12/calendar"

'Open the calendar and get the first appointment
Rec.Open CalendarURL
Set Rs.ActiveConnection = Rec.ActiveConnection
Rs.Source = "SELECT * from SCOPE('shallow traversal of """ & CalendarURL & """')"
Rs.Open
Rs.MoveFirst
ItemURL = Rs.Fields(CdoDAV.cdoHref)
IAppt.DataSource.Open ItemURL

'Use the Attendees object to get all attendees
Set IAtnds = IAppt.Attendees
For Index = 1 To IAtnds.Count
  Set IAtnd = IAtnds.Item(Index)
  Debug.Print IAtnd.Address
Next Index
© 2000-2001 Microsoft Corporation. All rights reserved.


AuditTrailEventLog CoClass

Records workflow event activity messages to an application log.

CLSID
CD001007-8B95-11D1-82DB-00C04FB1625D
ProgID
CDOWF.AuditTrailEventLog
Type Library
Microsoft® CDO Workflow Objects for Microsoft Exchange
Inproc Server
CDOWF.DLL
Threading Model
Both
Although CDOWF objects are labeled BOTH, they are not in fact thread safe. CDOWF objects do not support accessing one object from many threads.

Implemented Interfaces

IAuditTrail

Remarks

This is a sample audit trail provider that is supplied with Workflow for Microsoft® Exchange 2000 Server. This provider writes its entries to the Microsoft® Windows® 2000 event log when specified as the AuditTrailProvider property of the ProcessDefinition object. You can write your own audit trail provider by implementing the IAuditTrail interface.

See Also

CdoWfAuditTrailEvents

AuditTrailProvider

ProcessDefinition

IAuditTrail

© 2000-2001 Microsoft Corporation. All rights reserved.


BodyPart CoClass

Defines an object used to manipulate a body part of a message.

CLSID
Not applicable
ProgID
Not applicable
Type Library
Microsoft® CDO for Windows® 2000 Library
Microsoft CDO for Microsoft Exchange Library
Inproc Server
CDOSYS.DLL, CDOEX.DLL
Threading Model
Both

Implemented Interfaces

IBodyPart

OLE DB Row Access

Remarks

BodyPart objects make up the hierarchy of content and structural units for a message. Each BodyPart object can contain some part of a Message object's content, whether it is an attachment or a part of a MIME hierarchy of content. BodyPart objects can also act as structural units for a MIME-formatted message.

In a uuencode-formatted message, each Message object attachment is contained within a BodyPart object in the Message object's IBodyPart::BodyParts collection. In a MIME-formatted message, BodyPart objects act as the structural units of the MIME hierarchy, with the top-level Message object acting as the root. The BodyPart object may not necessarily contain content, such as when it acts as a MIME structural unit with Content-Type set to “multipart/alternative”. In this case, it simply contains other BodyPart objects in its IBodyPart.BodyParts collection, where each object contains the alternative representations of the content.

Each BodyPart object can contain header fields located in the IBodyPart::Fields collection. For objects that make up a MIME-formatted message, the Fields collection contains fields used to define the MIME headers for the part, such as Content-Type and Content-Disposition. Each of these fields resides in the urn:schemas:mailheader namespace (for example, urn:schemas:mailheader:content-type and urn:schemas:mailheader:content-disposition). When accessing these fields in the collection, you must use the fully qualified names to avoid possible ambiguity. A set of string constants is provided for use when accessing fields by name in the Fields collection.

In many cases, the BodyPart object contains a unit of content for a message, whether it is an attachment, an MHTML body part, simple ASCII text, or an inline image file. To access the content contained in a BodyPart object in either encoded or decoded format, you use the IBodyPart.GetDecodedContentStream and IBodyPart.GetEncodedContentStream methods, respectively. The encoding format used is defined with the urn:schemas:mailheader:content-transfer-encoding header field.

Instances of the BodyPart COM class cannot be created directly. They are always returned by instances of the Message COM class for manipulation of a particular body part.

For messages with a single text body part, use the Fields collection on the Message object to set values such as character set and encoding type. Do not use the Fields collection on the BodyPart object.

Example

The following code demonstrates using BodyPart objects to create a MIME-formatted message. In this case, it creates a two-part multipart/mixed message, where the first part is a multipart/alternative entity and the second is an image/gif entity. The multipart/alternative entity contains two subparts: a text/HTML subpart and a text/plain subpart.

[Visual Basic]
' Reference to Microsoft ActiveX Data Objects 2.5 Library
' Reference to Microsoft CDO for Exchange 2000 Library
Dim iMsg As New CDO.Message
Dim iBp As CDO.IBodyPart
Dim iBp1 As CDO.IBodyPart
Dim iBp2 As CDO.IBodyPart
Dim iFlds as ADODB.Fields
Dim iStrm as ADODB.Stream

Set iBp = iMsg   ' get IBodyPart on Message object

Set iFlds = iBp.Fields
iFlds("urn:schemas:mailheader:content-type") = "multipart/mixed"
iFlds.Update

Set iBp1 = iBp.AddBodyPart  ' Add a BodyPart object to the hierarchy

Set iBp2 = iBp1.AddBodyPart  ' text/plain
Set iFlds = iBp2.Fields
iFlds("urn:schemas:mailheader:content-type") = "text/plain"
iFlds("urn:schemas:mailheader:content-transfer-encoding") = _
    "quoted-printable"
        iFlds.Update

Set iStrm = iBp2.GetDecodedContentStream
iStrm.WriteText "This is a message"
iStrm.Flush

Set iBp2 = iBp1.AddBodyPart   ' text/html
Set iFlds = iBp2.Fields
iFlds("urn:schemas:mailheader:content-type") = "text/html"
iFlds("urn:schemas:mailheader:content-transfer-encoding") = _
    "quoted-printable"
iFlds.Update

Set iStrm = iBp2.GetDecodedContentStream
iStrm.WriteText "<html><h1>This is a message</h1></html>"
iStrm.Flush

' This may appear out of order, but we have to _reset_ the
' content-type for the "multipart/alternative" body part after adding
' the two representations.  If we set it before, it will be switched
' to "multipart/mixed" when we call the AddBodyPart() method on the
' object.

Set iFlds = iBp1.Fields
iFlds("urn:schemas:mailheader:content-type") = "multipart/alternative"
iFlds.Update

Set iBp1 = iBp.AddBodyPart    '  image/gif
Set iFlds = iBp1.Fields
iFlds("urn:schemas:mailheader:content-type") = "image/gif"
iFlds("urn:schemas:mailheader:content-transfer-encoding") = "base64"

Set iStrm = iBp1.GetDecodedContentStream
iStrm.LoadFromFile "c:\images\myimage.gif"
iStrm.Flush
[C++]
/*
  BuildMessageStreamAndSaveToFile()

  This routine demonstrates the use
  of the BodyPart object when constructing
  a Message object.

   You must have the following paths in your
  include path:
  %CommonProgramFiles%\system\ado
  %CommonProgramFiles%\microsoft shared\cdo

*/
#ifndef _CORE_EXAMPLE_HEADERS_INCLUDED
#define _CORE_EXAMPLE_HEADERS_INCLUDED
#import <msado15.dll> no_namespace
#import <cdoex.dll> no_namespace
#include <iostream.h>
#endif

void BuildMessageStreamAndSaveToFile()
{
      IMessagePtr  iMsg(__uuidof(Message));
      IBodyPartPtr iBp;
      IBodyPartPtr iBp1;
      IBodyPartPtr iBp2;
      FieldsPtr    Flds;
      _StreamPtr   Stm;

      /*
      **  multipart/mixed (root)
      */
      iBp   = iMsg;
      Flds  = iBp->Fields;
      Flds->Item["urn:schemas:mailheader:content-type"]->Value =
         _bstr_t("multipart/mixed");
      Flds->Update();

      /*
      ** multipart/alternative (child of root)
      */
      iBp1   = iBp->AddBodyPart(-1);  // multipart/altenative body part

      /*
      ** text/plain
      */
      iBp2   = iBp1->AddBodyPart(-1); // text/plain body part
      Flds   = iBp2->Fields;
      Flds->Item["urn:schemas:mailheader:content-type"]->Value =
         _bstr_t("text/plain");
      Flds->Item["urn:schemas:mailheader:content-transfer-encoding"]->Value =
         _bstr_t("quoted-printable");
      Flds->Update();

      Stm    = iBp2->GetDecodedContentStream();
      Stm->WriteText(_bstr_t("text version of message"),stWriteChar);
      Stm->Flush();

      /*
      ** text/html
      */
      iBp2   = iBp1->AddBodyPart(-1); // text/html body part
      Flds   = iBp2->Fields;
      Flds->Item["urn:schemas:mailheader:content-type"]->Value =
         _bstr_t("text/html");
      Flds->Item["urn:schemas:mailheader:content-transfer-encoding"]->Value =
         _bstr_t("quoted-printable");
      Flds->Update();

      Stm    = iBp2->GetDecodedContentStream();
      Stm->WriteText(_bstr_t("<html><p><em>html</em> version of message</p></html>"),stWriteChar);
      Stm->Flush();

      /*
      ** set multipart/alternative header
      */
      Flds   = iBp1->Fields;
      Flds->Item["urn:schemas:mailheader:content-type"]->Value =
         _bstr_t("multipart/alternative");
      Flds->Update();

      /*
      ** image/gif (child of root multipart/mixed)
      */
      iBp1   = iBp->AddBodyPart(-1);
      Flds   = iBp1->Fields;
      Flds->Item["urn:schemas:mailheader:content-type"]->Value =
         _bstr_t("image/gif");
      Flds->Item["urn:schemas:mailheader:content-transfer-encoding"]->Value =
         _bstr_t("base64");
      Flds->Update();

      Stm    = iBp1->GetDecodedContentStream();
      try
      {
         Stm->LoadFromFile(_bstr_t("..\\misc\\myimage.gif"));
         Stm->Flush();
      }
      catch(_com_error error)
      {
         cerr << "Error loading GIF file" << endl;
         cerr << _bstr_t(error.Description()) << endl;
         throw error;
      }

      /*
      ** Save message stream to disk
      */
      Stm    = iMsg->GetStream();
      try {
         Stm->SaveToFile(_bstr_t("message.eml"),adSaveCreateOverWrite);
      }
      catch(_com_error error) {
         cerr << "Error Saving file" << endl;
         cerr << _bstr_t(error.Description()) << endl;
         throw error;
      }

}


BodyParts CoClass

Defines an object used to manage a collection of BodyPart objects.

CLSID
Not applicable
ProgID
Not applicable
Type Library
Microsoft® CDO for Windows® 2000 Library,
Microsoft CDO for Microsoft® Exchange Server
Inproc Server
CDOSYS.DLL, CDOEX.DLL
Threading Model
Both

Implemented Interfaces

IBodyParts

Supported IDataSource Bindings

None

Remarks

Instances of the BodyParts COM class cannot be created directly. An object reference is always returned by BodyParts properties on other interfaces, such as the IBodyPart::BodyParts property.

Example

[Visual Basic]
Dim iMsg as new CDO.Message
Dim iBp as CDO.IBodyPart
Dim iBps as CDO.IBodyParts

iMsg.AddAttachment "c:\somefile.html"
iMsg.AddAttachment "c:\anotherfile.doc"
iMsg.CreateMHTMLBody "http://myserver/mypage.html", cdoSuppressAll

Set iBp = iMsg
Debug.Print "Root content-type: " & iBp.ContentMediaType
Set iBps = iBp.BodyParts

' loop through attachments
Dim i as Integer
For Each iBp in iBps
  Debug.Print "Level 1, item " & i & " " & iBp.ContentMediaType
  i = i + 1
Next iBp
' set recipients, etc

iMsg.Send
[C++]
#import "c:\program files\common files\system\ado\msado15.dll" no_namespace
#import "c:\winnt\system32\cdosys.dll" no_namespace
#include <iostream.h>
#include <assert.h>

main(){
  CoInitialize(NULL);  // single-threaded apartment
  {
   IBodyPartPtr   iBp;
   IBodyPartsPtr iBps;
   IMessagePtr iMsg(__uuidof(Message));

   iMsg->AddAttachment("c:\somefile.html","","");
   iMsg->AddAttachment("c:\anotherfile.doc","","");
   iMsg->CreateMHTMLBody("http://www.microsoft.com", cdoSuppressAll,"","");

   iBp = iMsg;
   // print the content media types for the body parts
   // this will print "multipart/mixed"
   cout << "Root content-type: " << iBp->ContentMediaType << endl;

   iBps = iBp->BodyParts;

   for(long i = 1;i<=iBps->Count;i++) {
     iBp = iBps->item[i];
     cout << "level 1, item " << i << " " << iBp->ContentMediaType << endl;
   }
   // in the above loop, you will get "multipart/alternative"
   // and, depending upon the attachments, something like
   // "text/html"
   // "application/octet-stream"

   // set recipients, etc

   iMsg->Send();
  }
  CoUninitialize();
  return 0;
}


CalendarMessage CoClass

Use to send and respond to meeting requests.

CLSID
CD000102-8B95-11D1-82DB-00C04FB1625D
ProgID
CDO.CalendarMessage
Type Library
Microsoft® CDO for Microsoft Exchange Library
Inproc Server
CDOEX.DLL
Threading Model
Both

Implemented Interfaces

IBodyPart

ICalendarMessage

IDataSource

IMessage

OLE DB Row Access

Supported IDataSource Bindings

IDataSource method | Target argument | Content class
Open | Microsoft Web Storage System item URL | urn:content-classes:calendarmessage
OpenObject | IRow _Record IStream _Stream IBodyPart | urn:content-classes:calendarmessage
SaveTo | Web Storage System item URL | N/A
SaveToContainer | Web Storage System folder URL | N/A
SaveToObject | IRow _Record IStream _Stream IBodyPart | N/A

Remarks

Because meeting requests are sent and received as messages with MIME body parts containing calendar content, this class accesses full messaging functionality with the IMessage, IBodyPart, and IDataSource interfaces.

The IBodyPart interface acts as the root of the hierarchy of MIME body parts in a message.

The CalendarMessage object encapsulates the meeting request as an e-mail message. It also provides access to the ICalendarParts interface that filters for body parts containing calendar content.

Request/Response Protocol

The CalendarMessage object serves the protocol requirements for the organizer, who sends a meeting request, and an attendee, who sends a meeting response. The following steps outline a typical scenario:

  1. The organizer creates an Appointment object, populated with the necessary property values such as the meeting location and times. The organizer adds Attendee objects to the Attendees collection.
  2. The Appointment object's CreateRequest method creates a CalendarMessage object that is sent with the Send method.
  3. An attendee receives a meeting request in a message containing at least one body part of calendar content. The CalendarMessage object's CalendarParts property accesses an ICalendarParts collection, and its GetUpdatedItem method instantiates an Appointment object with the meeting times, location, and other values from a calendar part in the meeting request message. That Appointment object is saved in the attendee's calendar folder.
  4. An attendee can respond by accepting, accepting tentatively, or declining the meeting request. To respond, the attendee creates a CalendarMessage object using the Appointment object's Accept, AcceptTentative, and Decline methods and sends a response message to the organizer with an optional text message. An attendee can also invite another person to the meeting using a CalendarMessage object.
  5. The organizer receives the response message and derives an Appointment object using the ICalendarParts collection and GetUpdatedItem method. The Attendee collection can be examined to determine the attendees who accepted or declined. The organizer saves the Appointment object to his or her calendar folder using the IDataSource.Save method. This updates the organizer's appointment item with the updated appointment information.

Example

[Visual Basic]
Function SendMeetingRequest(iMbx As CDO.IMailbox, sRecipEmail As String)

  Dim Config    As New Configuration
  Dim iAppt     As New Appointment
  Dim iCalMsg   As CalendarMessage
  Dim iAttn     As Attendee

  'Set the configuration fields
  Config.Fields(cdoMailboxURL) = iMbx.BaseFolder
  Config.Fields("CalendarLocation") = iMbx.Calendar
  Config.Fields(cdoSendUsingMethod) = cdoSendUsingExchange
  Config.Fields(cdoSendEmailAddress) = "User1@exchange.microsoft.com"
  Config.Fields.Update

  With iAppt
    .Configuration = Config

    'Set the appointment properties
    .StartTime = #9/5/1999 12:30:00 PM#
    .EndTime = #9/5/1999 1:30:00 PM#
    .Subject = "Lunch meeting"
    .Location = "Building B Cafeteria"
  End With

    'Add an attendee
    Set iAttn = .Attendees.Add
    iAttn.Address = sRecipEmail

   'Create the calendar message and send it
    Set iCalMsg = iAppt.CreateRequest
    Set iCalMsg.Configuration = Config

    iAppt.DataSource.SaveToContainer iMbx.Calendar

    iCalMsg.Message.Send

    Set SendMeetingRequest = iAppt

End Function
© 2000-2001 Microsoft Corporation. All rights reserved.


CalendarPart CoClass

Accesses any component of the CalendarParts collection on the CalendarMessage object.

CLSID
Not applicable
ProgID
Not applicable
Type Library
Microsoft® CDO for Microsoft Exchange Library
Inproc Server
CDOEX.DLL
Threading Model
Both

Implemented Interfaces

IAppointment

ICalendarPart

Supported IDataSource Bindings

None

Remarks

A CalendarPart object represents a body part that contains calendar content. You can examine each calendar part's appointment information with this object's IAppointment interface. If you want to work with a CalendarMessage object instantiated from a calendar part, use the GetAssociatedItem method.

Example

[Visual Basic]
Sub ProcessCalItemsForUser(Optional sUserUPN As String)

    Dim InfoNT As New WinNTSystemInfo
    Dim Info As New ADSystemInfo
    Dim iPer As New CDO.Person
    Dim iMbx As CDO.IMailbox

    ' If an empty string is passed, assume we have an
    ' authenticated user. We can bind directly to the
    ' Active Directory using the DN for the user in the
    ' ADSystemInfo.UserName property.

    ' Otherwise, attempt to bind by searching using the
    ' passed UPN.

    If sUserUPN = "" Or IsNull(sUserUPN) Then
        MsgBox "Bind"
        iPer.DataSource.Open "LDAP://" & Info.UserName
    Else
        MsgBox "mailto baby!"
        iPer.DataSource.Open "mailto:" & sUserUPN
    End If

    Set iMbx = iPer
    ProcessCalItemsInInbox iMbx

End Sub

Sub ProcessCalItemsInInbox(iMbx As CDO.IMailbox)

  Dim Config       As New Configuration
  Dim Rs           As New ADODB.Recordset
  Dim Rec          As New ADODB.Record
  Dim Conn         As New ADODB.Connection
  Dim iCalMsg      As New CalendarMessage
  Dim iCalPart     As ICalendarPart
  Dim iAppt        As Appointment
  Dim ContentClass As String

  Conn.Provider = "ExoLEDB.DataSource"
  Conn.Open iMbx.BaseFolder

  'Set the configuration fields for the appointment objects
  Config.Fields(cdoMailboxURL) = iMbx.BaseFolder
  Config.Fields("CalendarLocation") = iMbx.Calendar
  Config.Fields(cdoActiveConnection) = Conn
  Config.Fields.Update

  'Open a recordset for the items in the inbox folder
  Rec.Open iMbx.Inbox, Conn
  Set Rs.ActiveConnection = Rec.ActiveConnection
  Rs.Source = "select ""DAV:href"",""DAV:contentclass"" from scope('shallow traversal of """ & iMbx.Inbox & """')" & _
              " where ""DAV:contentclass"" = 'urn:content-classes:calendarmessage'"
  Rs.Open

  'Enumerate the recordset, checking each item's content class
  Rs.MoveFirst

  Do Until Rs.EOF
      iCalMsg.DataSource.Open Rs(0), Conn, adModeReadWrite
      iCalMsg.Configuration = Config
      Debug.Print "Message subject: " & iCalMsg.Message.Subject
      'Get each calendar part
      For Each iCalPart In iCalMsg.CalendarParts
        Set iAppt = iCalPart.GetUpdatedItem(iMbx.Calendar)
        ' Work with Appointment here.
        ' Delete the calendar message from the inbox.
        iAppt.DataSource.Save
        Rs.Delete
      Next iCalPart
      Rs.MoveNext
  Loop
End Sub
© 2000-2001 Microsoft Corporation. All rights reserved.


CalendarParts CoClass

Defines an object used to manage a collection of CalendarPart objects.

CLSID
Not applicable
ProgID
Not applicable
Type Library
Microsoft® CDO for Microsoft Exchange Library
Inproc Server
CDOEX.DLL
Threading Model
Both

Implemented Interfaces

ICalendarParts

Supported IDataSource Bindings

None

Remarks

The CalendarParts COM class cannot be created directly, but it can be returned by using the CalendarPart property on a CalendarMessage object.

Example

The following code example checks the inbox of a user on an Exchange server in an Exchange domain. When it finds a calendar message, it prints the subject line of the message and the method of each calendar part in the calendar parts collection.

Note This example uses a file URL with the Exchange OLE DB (ExOLEDB) provider. The ExOLEDB provider also supports the HTTP URL scheme.

[Visual Basic]
Dim InboxURL     As     String
Dim CalendarURL  As     String
Dim ItemURL      As     String
Dim Rs           As New ADODB.Recordset
Dim Rec          As New ADODB.Record
Dim iCalMsg      As New CalendarMessage
Dim iCalPart     As     ICalendarPart
Dim iAppt        As     Appointment
Dim Index        As     Integer
Dim ContentClass As     String
Dim Config       As New Configuration

InboxURL = "file://./backofficestorage/exchange.microsoft.com/MBX/user12/inbox/"
CalendarURL = "file://./backofficestorage/exchange.microsoft.com/MBX/user12/calendar/"

'Set the configuration fields for the appointment objects
Config.Fields(cdoSendEmailAddress) = "user12@exchange.microsoft.com"
Config.Fields("CalendarLocation") = CalendarURL
Config.Fields.Update

'Open a recordset for the items in the inbox folder
Rec.Open InboxURL
Set Rs.ActiveConnection = Rec.ActiveConnection
Rs.Source = "select ""DAV:href"",""DAV:contentclass"" from scope('shallow traversal of """ & InboxURL & """')"
Rs.Open , , , adLockOptimistic

'Enumerate the recordset, checking each item's content class
Rs.MoveFirst
Do Until Rs.EOF
  'Get the content class of each item
  ContentClass = Rs.Fields("DAV:contentclass").Value
  'Test the content class for calendar message
  If ContentClass = "urn:content-classes:calendarmessage" Then
    'Open the calendar message
    ItemURL = Rs.Fields(CdoDAV.cdoHref).Value
    iCalMsg.DataSource.Open ItemURL
    iCalMsg.Configuration = Config
    Debug.Print "Message subject: " & iCalMsg.Message.Subject
    'Get each calendar part
    For Index = 1 To iCalMsg.CalendarParts.Count
      Set iCalPart = iCalMsg.CalendarParts(Index)
      Set iAppt = iCalPart.GetUpdatedItem
      Debug.Print "Part " & Index & " Method: " & iCalPart.CalendarMethod
    Next Index
    'Delete the calendar message from the inbox
    Rs.Delete
  End If

Rs.MoveNext
Loop
© 2000-2001 Microsoft Corporation. All rights reserved.


Configuration CoClass

Defines an object used to manage the configuration settings used with other CDO objects.

CLSID
CD000002-8B95-11D1-82DB-00C04FB1625D
ProgID
CDO.Configuration
Type Library
Microsoft® CDO for Windows® 2000 Library,
Microsoft CDO for Microsoft Exchange Server
Inproc Server
CDOSYS.DLL, CDOEX.DLL
Threading Model
Both

Implemented Interfaces

IConfiguration

OLE DB Row Access

Supported IDataSource Bindings

None

Remarks

Configuration settings are made up of a set of fields (properties) that are simply name/value pairs. Each field is represented as an ADO Field object contained in an ADO Fields collection. Most configuration fields used for messaging are in the http://schemas.microsoft.com/cdo/configuration/ namespace. For calendaring applications, you specify a time zone using the urn:schemas:calendar:timezone and urn:schemas:calendar:timezoneid fields, and a calendar folder URL using the "CalendarLocation" field.

To increase performance, you can share a single Configuration object amongst your other CDO objects, and cache the object for reuse. For example, you can gather the configuration information for a particular user in an ASP application Session_OnStart event, and then store the Configuration object in the ASP Session collection. When each ASP page within the session executes, you can retrieve the Configuration object from the Session collection and attach it to each object. You therefore increase performance by not re-creating and populating a Configuration object for each page or for each object you use.

Example

Assume that the machine on which this example will run has neither an SMTP service nor Outlook Express installed. In this case, we need to send the message through some SMTP service on the network and must completely configure the Message object. Further assume that the SMTP service through which we intend to send messages requires us to authenticate ourselves using the basic (clear-text) authentication mechanism. An instance of the Configuration COM class is created and the configuration fields in the object are set with values such as the required SMTP server name, port, authentication, and username and password. Additional values are set, such as the e-mail address, account name and reply e-mail address. The values used in the example are listed in the following table. Each field is in the http://schemas.microsoft.com/cdo/configuration/ namespace.

Field | Value
smtpserver | fakesmtp.microsoft.com
smtpserverport | 25
sendingusing | cdoSendUsingPort (2)
smtpaccountname | My Name
sendemailaddress | "My Self" <myself@microsoft.com>
smtpuserreplyemailaddress | "Another" <another@microsoft.com>
smtpauthenticate | cdoBasic (1)
sendusername | domain\username
sendpassword | password

Once the Configuration object has been populated with relevant configuration information, the object reference is set on a Message object. The Message object uses the configuration information to send the message. In the examples that follow, the fully qualified field names are used to elucidate the process. However, there are string constants (as type library modules) in the type library for each of these field names.

[Visual Basic]
  ' Reference to Microsoft ActiveX Data Object 2.5 Library
  ' Reference to Microsoft CDO for Exchange 2000 Library
  Dim iConf as New CDO.Configuration
  Dim Flds as ADODB.Fields
  Set Flds = iConf.Fields

    ' The full  field name strings are used below to elucidate this process.
    ' The CDO for Windows 2000 type library contains string Modules
    ' that provide these values as named constants.
    ' Use these module constants to avoid typos, etc

  Flds("http://schemas.microsoft.com/cdo/configuration/smtpserver")               = "fakesmtp.microsoft.com"
  Flds("http://schemas.microsoft.com/cdo/configuration/smtpserverport")           = 25
  Flds("http://schemas.microsoft.com/cdo/configuration/sendusing")                = cdoSendUsingPort  ' CdoSendUsing enum value =  2
  Flds("http://schemas.microsoft.com/cdo/configuration/smtpaccountname")          = "My Name"
  Flds("http://schemas.microsoft.com/cdo/configuration/sendemailaddress")     = """MySelf"" <myself@microsoft.com>"
  Flds("http://schemas.microsoft.com/cdo/configuration/smtpuserreplyemailaddress")= """Another"" <another@microsoft.com>"
  Flds("http://schemas.microsoft.com/cdo/configuration/smtpauthenticate")         = cdoBasic
  Flds("http://schemas.microsoft.com/cdo/configuration/sendusername") = "domain\username"
  Flds("http://schemas.microsoft.com/cdo/configuration/sendpassword")    = "password"
  Flds.Update

  '  The Item property on the Fields interface is the default.
  '  The Value property on the returned Field interface is the default
  '  Fully expanded, each line would look like this:
  '
  '  Flds.Item("property").Value = [value]

  Dim iMsg as New CDO.Message
  Set iMsg.Configuration = iConf

  ' ... compose message; add attachments, etc

  iMsg.Send   ' Configuration settings in Config object are used to send the message
[C++]
#import "c:\program files\common files\system\ado\msado15.dll" no_namespace
#import "c:\program files\common files\microsoft shared\cdo\cdoex.dll" no_namespace

main( ){

  CoInitialize(NULL);
  {
    IMessagePtr IMsg(__uuidof(Message));
    IConfigurationPtr iConfig = Msg->Configuration;

    FieldsPtr Flds;
    FieldPtr Fld;
    Flds = iConfig->Fields;

    // The full strings for field names are used to elucidate the process.
    // The cdoex.h header file contains BSTR constants that
    // can be used to avoid typos, etc

    Flds->Item[_variant_t("http://schemas.microsoft.com/cdo/configuration/smtpserver")]->Value               = _variant_t("fakesmtp.microsoft.com") ;
    Flds->Item[_variant_t("http://schemas.microsoft.com/cdo/configuration/smtpserverport")]->Value           = _variant_t((long)25) ;
    Flds->Item[_variant_t("http://schemas.microsoft.com/cdo/configuration/sendusing")]->Value                = _variant_t((int)cdoSendUsingPort) ;  // this value is 2
    Flds->Item[_variant_t("http://schemas.microsoft.com/cdo/configuration/smtpaccountname")]->Value          = _variant_t("My Name") ;
    Flds->Item[_variant_t("http://schemas.microsoft.com/cdo/configuration/sendemailaddress")]->Value     = _variant_t("\"MySelf\" <myself@microsoft.com>") ;
    Flds->Item[_variant_t("http://schemas.microsoft.com/cdo/configuration/smtpuserreplyemailaddress")]->Value= _variant_t("\"Another\" <another@microsoft.com>") ;
    Flds->Item[_variant_t("http://schemas.microsoft.com/cdo/configuration/smtpauthenticate")]->Value         = _variant_t((long)cdoBasic) ;
    Flds->Item[_variant_t("http://schemas.microsoft.com/cdo/configuration/sendusername")]->Value = _variant_t("domain\\username") ;
    Flds->Item[_variant_t("http://schemas.microsoft.com/cdo/configuration/sendpassword")]->Value    = _variant_t("password") ;
    Flds->Update();

    /*
    ** These string contants are available in the cdosys.h header file
    ** but are not put in the cdosys.tlh file when #import runs.
    **

       const BSTR cdoSMTPServer = = L"http://schemas.microsoft.com/cdo/configuration/smtpserver";

       and so on additionally for each of these:

       cdoSMTPServer
       cdoSMTPAccountName
       cdoSMTPAuthenticate
       cdoSendUsingMethod    (you can use the CdoSendUsing enumeration for this)
       cdoSMTPServerPort
       cdoSendEmailAddress
       cdoSendUserName
       cdoSendUserPassword
       cdoSMTPUserReplyEmailAddress
    **
    */

    iMsg->Configuration = iConfig;

    // ... compose message; add attachments, etc

    iMsg->Send();

  }
  CoUninitialize();
}


DropDirectory CoClass

Defines an object used to access a file system that contains messages, such as the SMTP service drop directory, on a Microsoft® Windows 2000 Server.

Note Because DropDirectory is used only for accessing messages on a file system, it is not useful in CDO for Exchange where messages are saved in the public or private stores (in MDBs).

CLSID
CD000004-8B95-11D1-82DB-00C04FB1625D
ProgID
CDO.DropDirectory
Type Library
Microsoft CDO for Windows 2000 Library,
Microsoft CDO for Microsoft Exchange Server
Inproc Server
CDOSYS.DLL, CDOEX.DLL
Threading Model
Both

Implemented Interfaces

IDropDirectory

Example

[Visual Basic]
Dim iDropDir as new CDO.DropDirectory
Dim iMsgs as CDO.IMessages

Set iMessages = iDropDir.GetMessages ' get from SMTP drop directory
Dim iMsg as CDO.Message

For Each iMessage in iMsgs
  Debug.Print iMsg .From
  Debug.Print iMsg .To
  Debug.Print iMsg .Subject
  Debug.Pring iMsg .TextBody
Next iMessage
[C++]
#import "c:\program files\common files\system\ado\msado15.dll" no_namespace
#import "c:\winnt\system32\cdosys.dll" no_namespace
#include <iostream.h>

main() {
  CoInitialize();
  {
    IDropDirectoryPtr iDropDir(__uuidof(DropDirectory));
    IMessagesPtr iMessages;
    iMessages = iDropDir->GetMessages("");
    long Count = iMessages->Count;
    for(long i=1;i<=Count;i++) {
      IMessagePtr iMsg;
      iMsg = iMessages->item[i];
      cout << iMsg->To << endl;
      cout << iMsg->From << endl;
      cout << iMsg->Subject << endl;
      cout << iMsg->TextBody << endl;
    }
  }
  CoUninitialize();

}


Exception CoClass

Defines an exception in the schedule for a recurring meeting.

CLSID
Not applicable
ProgID
Not applicable
Type Library
Microsoft® CDO for Microsoft Exchange Library
Inproc Server
CDOEX.DLL
Threading Model
Both

Implemented Interfaces

IException

Supported IDataSource Bindings

None

Remarks

Exceptions are defined after a RecurrencePattern object has created a recurring meeting. An Exception object obtains an individual exception contained within the Exceptions collection available on an Appointment object. You can create as many exceptions as necessary to accommodate your schedule.

Example

This code example adds to the RecurrencePattern object.

[Visual Basic]
Sub RecurringMeetingRequest()
  Dim myAppt As New CDO.Appointment
  Dim RecPat As CDO.RecurrencePattern
  Dim myEx As CDO.Exception
  Dim iAttendee  As Attendee

  'Create the recurring appointment
  With myAppt
    .Subject = "Investment Reviews"
    .StartTime = "1/6/99 10:30AM"
    .EndTime = "1/6/99 11:30AM"
    .Location = "Skybridge Atrium"
    Set iAttendee = myAppt.Attendees.Add
    iAttendee.Address = "someone@" & DomainName
    iAttendee.Role = cdoRequiredParticipant
    Set RecPat = .RecurrencePatterns.Add("ADD")
    RecPat.Frequency = cdoFrequencyWeekly
    RecPat.Occurences = 10
    .CreateRequest.Message.Send
  End With

  'Now add an exception
   Set myEx = myAppt.Exceptions.Add("MODIFY")
   With myEx

     'Identify the recurring appt with the recurrenceID
     'that is the start time of the recurring appointment
     'for a particular day
     .RecurrenceID = "1/6/99 10:30AM"

     'Set the exception start and end times
     .StartTime = "1/6/99 3:00PM"
     .EndTime = "1/6/99 4:00PM"

  End With
 End Sub
© 2000-2001 Microsoft Corporation. All rights reserved.


Exceptions CoClass

Defines an object used to manage a collection of Exception objects.

CLSID
Not applicable
ProgID
Not applicable
Type Library
Microsoft® CDO for Microsoft Exchange Library
Inproc Server
CDOEX.DLL
Threading Model
Both

Implemented Interfaces

IExceptions

Supported IDataSource Bindings

None

© 2000-2001 Microsoft Corporation. All rights reserved.


ExchangeServer CoClass

Defines an object that can access and modify information about the Microsoft® Exchange 2000 Server.

CLSID
25150F27-5734-11D2-A593-00C04F990D8A
ProgID
CDOEXM.ExchangeServer
Type Library
Microsoft® CDO for Exchange Management Library
Inproc Server
CDOEXM.DLL
Threading Model
Both

Implemented Interfaces

IExchangeServer

IDataSource2

Supported IDataSource2 Bindings

Data pertaining to a server can reside in both the Microsoft® Windows® Active Directory™ and the Microsoft® Exchange 2000 Server. In most cases you will use the IDataSource2 interface to bind to data in Active Directory using the LDAP address protocol. See Active Directory and CDOEXM for related information.

Remarks

Instances of the Exchange Server COM class give you access to information pertaining to the Exchange 2000 Server. The primary and default interface on ExchangeServer objects is the IExchangeServer. You can use this interface to get information such as the name of the server, server type, server version, and what storage groups are on the server. You can also set server characteristics, such as enabling or disabling message tracking or setting the days before log files are removed.


Folder CoClass

Represents a folder in a public or private Microsoft® Web Storage System.

CLSID
CD00010E-8B95-11D1-82DB-00C04FB1625D
ProgID
CDO.Folder
Type Library
Microsoft® CDO for Microsoft Exchange Library
Inproc Server
CDOEX.DLL
Threading Model
Both

Implemented Interfaces

IDataSource

IFolder

OLE DB Row Access

Remarks

The Folder object represents a folder in any public or private Web Storage System. Folders can contain messages, appointments, or other folders in a structure similar to a file system of directories. You can use a Folder object to get the URL to a user's inbox, calendar, or folder, and process the items it contains.

For more information about the Folder object, see Working with Folders and Items.


FolderTree CoClass

Defines an object for creating and modifying top-level folders in Microsoft® Exchange 2000 Server MDBs.

CLSID
25150F23-5734-11D2-A593-00C04F990D8A
ProgID
CDOEXM.FolderTree
Type Library
Microsoft CDO for Exchange Management Library
Inproc Server
CDOEXM.DLL
Threading Model
Both

Implemented Interfaces

IFolderTree

IDataSource2

Supported IDataSource2 Bindings

Data pertaining to Top Level Hierarchies in Microsoft® Exchange 2000 Server can reside in both Microsoft® Windows® Active Directory™ and Exchange 2000 Server. In most cases you will use the IDataSource2 interface to bind to data in Active Directory using the Lightweight Directory Access Protocol (LDAP) address protocol. See Active Directory and CDOEXM for related information.

Remarks

Instances of the FolderTree COM class allow you to create and modify top-level folders in Exchange 2000 Server MDBs. The default interface on FolderTree objects is IFolderTree.

Multiple servers can contain replicas of the entire folder tree, or subsets of the folder tree. You can have only one replica of a folder tree per server.

See Also

Web Storage System Configuration

Creating a Folder Tree

© 2000-2001 Microsoft Corporation. All rights reserved.


MailboxStoreDB CoClass

Defines an object for managing a mailbox store.

CLSID
25150F25-5734-11D2-A593-00C04F990D8A
ProgID
CDOEXM.MailboxStoreDB
Type Library
Microsoft® CDO for Exchange Management Library
Inproc Server
CDOEXM.DLL
Threading Model
Both

Implemented Interfaces

IMailboxStoreDB

IDataSource2

Supported IDataSource2 Bindings

Data pertaining to Microsoft® Exchange 2000 mailbox storesServer can reside in both the Microsoft® Windows® Active Directory™ and Exchange 2000 Server. In most cases you will use the IDataSource2 interface to bind to data in Active Directory using the LDAP address protocol. See Active Directory and CDOEXM for related information.

Remarks

An instance of the MailboxStoreDB COM class allows you to manage the mailbox store of a single recipient. The default interface on the MailboxStoreDB object is IMailboxStoreDB. You can use this interface to move, mount, or dismount a mailbox store, or to access and set information pertaining to a mailbox store.

Example

Visual Basic

Reserved for future use.


Message CoClass

Defines an object that represents a message.

CLSID
CD000001-8B95-11D1-82DB-00C04FB1625D
ProgID
CDO.Message
Type Library
Microsoft® CDO for Windows® 2000 Library
Microsoft CDO for Microsoft Exchange Library
Inproc Server
CDOSYS.DLL
CDOEX.DLL
Threading Model
Both

Implemented Interfaces

IBodyPart

IDataSource

IMessage

OLE DB Row Access

Supported IDataSource Bindings

IDataSource Method | Target Argument | Content Class
Open | Microsoft® Web Storage System item URL | urn:content-classes:message urn:content-classes:calendarmessage
OpenObject | IRow _Record IStream _Stream IBodyPart | urn:content-classes:message urn:content-classes:calendarmessage
SaveTo | Web Storage System item URL | N/A
SaveToContainer | Web Storage System folder URL (GUID is generated for new item name) | N/A
SaveToObject | IRow _Record IStream _Stream IBodyPart | N/A

Remarks

An instance of the Message COM class represents a message. The primary and default interface on Message objects is the IMessage interface. You can use this interface to access the messaging-specific functionality of the object, including addressing the message, adding content, sending, posting, or responding to the message.

Messages contain a set of message headers that contain information such as to whom the message is to be sent, to whom carbon copies are to be sent, and so on. The most common message header fields are present as properties on the IMessage interface, and all of these fields are accessible using the Message object's Fields collection. All fields reside in some namespace, such as urn:schemas:mailheader, for the purpose of rendering them unique. In other words, when accessing the field in the Fields collection, you must use the fully qualified name of the field, such as urn:schemas:mailheader:subject for the message subject or urn:schemas:httpmail:textdescription for the text/plain part of the message.

The IMessage interface provides a set of top-level methods and properties designed to make creating the most common message content straightforward and intuitive. Such methods include CreateMHTMLBody, AddBodyPart, and AddAttachment. Properties include TextBody and HTMLBody.

For MIME-formatted messages, the Message object acts as the root body part of the MIME body part hierarchy. This functionality is provided through the exposed IBodyPart interface on the object. The IMessage interface provides the BodyPart property that returns this interface on the object. You can use BodyPart, the GetInterface method, or standard mechanisms such as Set (in Microsoft Visual Basic®) and QueryInterface (in C++) to navigate to this interface.

To facilitate the easy transfer of message data to and from other objects, the Message object provides an implementation of the IDataSource interface. Using methods and properties on this interface, you can access embedded messages in other messages, and embed messages in other messages. The IMessage interface provides the DataSource property to allow navigating to the IDataSource interface on the object.

CDO Messaging Using Exchange

CDO Messaging has additional capabilities with Exchange 2000 Server.

To send messages using Exchange (through the Exchange mail submission URI), you set the http://schemas.microsoft.com/cdo/configuration/sendusing field to cdoSendUsingExchange in the Message object's Configuration object. Similarly, you set the http://schemas.microsoft.com/cdo/configuration/postusing field to cdoPostUsingExchange to post using Exchange.

When you send or post messages using Exchange, CDO needs a connection to the user's Exchange mailbox. You can specify the URL to the user's mailbox folder using the http://schemas.microsoft.com/cdo/configuration/mailboxurl property in the Message object's Configuration object. If you do not specify the URL, CDO searches Active Directory™ for the necessary information to construct this URL using the user principal name found in the http://schemas.microsoft.com/cdo/configuration/sendusername or http://schemas.microsoft.com/cdo/configuration/postusername configuration fields.

The Message object's data source is changed when you send or post messages using Exchange. If the object was previously bound to an item in the Web Storage System, that binding is lost. You can override this behavior by specifying an open Connection object in the http://schemas.microsoft.com/cdo/configuration/activeconnection configuration field. If this object reference is present in the Configuration Fields collection, this Connection object is used to send or post the message. If the Connection object is not open and bound to the user's mailbox before the message is sent, CDO generates an error. If you want to send the message within a transaction, you must manually start and commit it using the referenced Connection object.

You can post directly to a public folder by specifying the folder's URL in the http://schemas.microsoft.com/exchange/hardlinklist property. Although this field is multivalued, you can only specify one folder URL.

Note There is a difference between saving a message to a folder and posting to a folder. Posting sets property values such as the post date and performs validations. You can examine the X-Unsent field to determine if a particular message was posted.

Example

[Visual Basic]
' Reference to CDO for Exchange 2000 Library
' Reference to ActiveX Data Objects 2.5 Library
' Reference to Active DS Type Library

Sub Main()

    Dim Info As New ADSystemInfo
    Dim InfoNT As New WinNTSystemInfo
    Dim iPer As New CDO.Person
    Dim sTo As String
    Dim sFrom As String
    Dim sSubject As String
    Dim sText As String

    sTo = InfoNT.UserName & "@" & Info.DomainDNSName
    sFrom = sTo
    sSubject = "Subject"
    sText = "Text of message."

    iPer.DataSource.Open "LDAP://" & Info.UserName

    Dim iMbx As CDO.IMailbox
    Set iMbx = iPer

    SendMessageUsingExchange sTo, sFrom, sSubject, sText, iMbx.BaseFolder

End Sub

Sub SendMessageUsingExchange(sTo As String, sFrom As String, sSubject As String, sText As String, sMailboxURL As String)

    Dim iMsg As New CDO.Message
    Dim iBp As CDO.IBodyPart
    Dim Flds As ADODB.Fields
    Dim Conn As New ADODB.Connection
    Dim Stm As ADODB.Stream

    Conn.Provider = "ExOLEDB.DataSource"
    Conn.Open sMailboxURL

    Dim iConf As New CDO.Configuration
    Set Flds = iConf.Fields

    Flds(cdoSendUsingMethod) = cdoSendUsingExchange
    Flds(cdoMailboxURL) = sMailboxURL
    Flds(cdoActiveConnection) = Conn
    Flds.Update

    With iMsg
     Set .Configuration = iConf
         .To = sTo
         .From = sFrom
         .Subject = sSubject
         .TextBody = sText

      Set iBp = .AddAttachment("c:\wordfile.doc")
      Set Stm = .GetStream
      Stm.SaveToFile "c:\mysavedmessage.eml", adSaveCreateOverWrite
        .Send
    End With

End Sub
[VBScript]
<Job id="sendselfmessage">
<reference object="cdo.message"/>
<reference object="adodb.connection"/>
<script language="VBScript">

 Dim Info
 Set Info = CreateObject("ADSystemInfo")
 Dim InfoNT
 Set InfoNT = CreateObject("WinNTSystemInfo")

 sTo = InfoNT.UserName & "@" & Info.DomainDNSName
 sFrom = sTo
 sSubject = "Subject"
 sText = "Text of message."

 Dim iPer
 Set iPer = CreateObject("CDO.Person")
 iPer.DataSource.Open "LDAP://" & Info.UserName

 Dim iMbx
 Set iMbx = iPer.GetInterface("IMailbox")

 SendMessageUsingExchange sTo, sFrom, sSubject, sText, iMbx.BaseFolder

Sub SendMessageUsingExchange( sTo, sFrom, sSubject, sText, sMailboxURL)

    Dim iMsg
    Set iMsg = CreateObject("CDO.Message")
    Dim iBp
    Dim Flds
    Dim Conn
    Dim Stm
    Set Conn = CreateObject("ADODB.Connection")
    Conn.Provider = "ExOLEDB.DataSource"
    Conn.Open sMailboxURL

    Dim iConf
    Set iConf = CreateObject("CDO.Configuration")
    Set Flds = iConf.Fields

    Flds(cdoSendUsingMethod)  = cdoSendUsingExchange
    Flds(cdoMailboxURL)       = sMailboxURL
    Flds(cdoActiveConnection) = Conn
    Flds.Update

    With iMsg
     Set .Configuration = iConf
         .To       = sTo
         .From     = sFrom
         .Subject  = sSubject
         .TextBody = sText

      Set iBp = .AddAttachment("c:\wordfile.doc")
      Set Stm = .GetStream
      Stm.SaveToFile "c:\mysavedmessage.eml", adSaveCreateOverWrite
        .Send
    End With

End Sub

</script>
</Job>
[C++]
 /*
  You must have the following paths in your
  include path:
  %CommonProgramFiles%\system\ado
  %CommonProgramFiles%\microsoft shared\cdo
  are in the INCLUDE path.
  Import the type libraries into the project:

  #import <msado15.dll> no_namespace raw_interfaces_only
  #import <cdoex.dll>   no_namespace raw_interfaces_only

 */
#ifndef _CORE_EXAMPLE_HEADERS_INCLUDED
#define _CORE_EXAMPLE_HEADERS_INCLUDED
#import <msado15.dll> no_namespace
#import <cdoex.dll> no_namespace
#include <iostream.h>
#endif

IMessagePtr CreateSampleMessage2() {

   IMessagePtr      pmsg(__uuidof(Message));
   IBodyPartPtr      bp;
   IConfigurationPtr   config(__uuidof(Configuration));
   FieldsPtr      flds;
   FieldPtr      fld;
   _StreamPtr      stm;

   _bstr_t bstrEmpty("");

   pmsg->To      = "\"Some One\" <someone@microsoft.com>, \"Another\" <another@microsoft.com>";
   pmsg->From      = "\"ThirdPerson\" <thirdperson@microsoft.com>, \"Fourth\" <fourth@microsoft.com>";
   pmsg->Sender   = "\"Finally\" <finally@microsoft.com>";
   pmsg->Subject   =   "A really cool message.";

   /*
   ** Get current directory so that relative paths
   ** can be expanded. This is needed for AddAttachment.
   */

   LPTSTR buf = NULL;
   DWORD buflen = 0;
   _bstr_t path;
   if( ( buflen = GetCurrentDirectory(buflen,NULL) ) > 0 ) {
      buf = new TCHAR[buflen+1];
      GetCurrentDirectory(buflen+1,buf);
      path = buf;
      delete [] buf;
   }
   else {
      cerr << "Error getting current directory" << endl;;
      throw _com_error(GetLastError());
   }

   try {
      bp = pmsg->AddAttachment(path + _bstr_t("\\..\\misc\\wordfile.doc"),
                           bstrEmpty,
                           bstrEmpty);

      bp->Fields->Item["urn:schemas:mailheader:content-type"]->Value = variant_t("application/msword");
      bp->Fields->Update();
      bp = pmsg->AddAttachment(path + _bstr_t("\\..\\misc\\message2.eml"),
                           bstrEmpty,
                           bstrEmpty);
      bp->Fields->Item["urn:schemas:mailheader:content-type"]->Value = _variant_t("message/rfc822");
      bp->Fields->Update();

      pmsg->CreateMHTMLBody(_bstr_t("http://msdn.microsoft.com"),cdoSuppressAll,_bstr_t(""),_bstr_t(""));
   }
   catch(_com_error e) {
      cerr << "Error creating sample message!" << endl;
      throw e;
   }

   // Save a copy to the local file system.
   stm = pmsg->GetStream();
   stm->SaveToFile(_bstr_t("savemymessage.eml"),adSaveCreateOverWrite);

   return pmsg;
}


Item CoClass

Provides a generic implementation of any resource in the Microsoft® Exchange 2000 Server Web Storage System.

CLSID
CD000112-8B95-11D1-82DB-00C04FB1625D
ProgID
CDO.Item
Type Library
Microsoft CDO for Microsoft Exchange Library
Inproc Server
CDOEX.DLL
Threading Model
Both

Implemented Interfaces

IDataSource

IItem

OLE DB Row Access

Supported IDataSource Bindings

IDataSource method | Target argument | Content class
Open | Web Storage System item URL | All content classes
OpenObject | IRow _Record IStream _Stream IBodyPart | All content classes
SaveTo | Web Storage System item URL | N/A
SaveToContainer | Web Storage System folder URL | N/A
SaveToObject | IRow _Record IStream _Stream IBodyPart | N/A

Remarks

You can use this class to open any folder or item as a generic CDO Configuration object, regardless of its content class.

Similar to an ADO Record object, an Item object provides access to streams and schema fields; it has convenient access to CDO Configuration objects and fields collections. Core item schema properties are also properties on the IItem interface.

Example

This code example opens an Item object from the URL of a valid object.

[Visual Basic]
'Assume oRec is a ADO Record object

Dim oI As New CDO.item
oI.DataSource.Open oRec.Source
Debug.Print oI.DisplayName
© 2000-2001 Microsoft Corporation. All rights reserved.


Person CoClass

Represents the attributes for an individual person in a Microsoft® Windows® 2000 Active Directory™ structure or a Microsoft Web Storage System.

CLSID
CD000107-8B95-11D1-82DB-00C04FB1625D
ProgID
CDO.Person
Type Library
Microsoft CDO for Microsoft Exchange Library
Inproc Server
CDOEX.DLL
Threading Model
Both

Implemented Interfaces

IDataSource

IPerson

IMailbox

OLE DB Row Access

Supported IDataSource Bindings

IDataSource Method | Target Argument | Content Class of Target
Open | Web Storage System item URL LDAP URLs Mailto URLs | urn:content-classes:person
OpenObject | IRow _Record | urn:content-classes:person
SaveTo | Web Storage System item URL LDAP URLs | N/A
SaveToContainer | Web Storage System folder URL LDAP URLs | N/A
SaveToObject | IRow _Record | N/A

Remarks

For more information about the Person object, see Creating Contact Applications.


ProcessDefinition CoClass

Defines the process logic for a workflow application.

CLSID
CD001002-8B95-11D1-82DB-00C04FB1625D
ProgID
CDOWF.ProcessDefinition
Type Library
Microsoft® CDO Workflow Objects for Microsoft Exchange
Inproc Server
CDOWF.DLL
Threading Model
Both
Although CDOWF objects are labeled BOTH, they are not thread safe. Collaboration Data Objects Workflow (CDOWF) objects do not support accessing one object from many threads.

Implemented Interfaces

IProcessDefinition (default)

IDataSource

Remarks

The ProcessDefinition COM class encapsulates the business logic and policies of a workflow application, and is used for:

  • Transferring work items between people.
  • Tracking the state of individual work items.
  • Server-side control of work item status changes
  • Automatic handling of work item exceptions.

The ProcessDefinition object supports data access through the IDataSource interface that enables you to manage the properties of the ProcessDefinition object. You store the business logic of a workflow application as the ActionTable property of the ProcessDefinition object. The action table has been previously created as an ADODB record set. The action table can contain script, can reference a set of common script functions, or can reference custom COM objects as actions or conditions.

Example

The following example declares two variable names for a ProcessDefinition object and an IDataSource interface, creates a ProcessDefinition object in memory, gets the IDataSource interface on the ProcessDefinition object, and opens the ProcessDefinition item for read/write access. With the iPD object you can now set various properties of the ProcessDefinition item and use the iDsrc interface to save the changes back to the ProcessDefinition item. ProcDefURL must be a valid URL to the ProcessDefinition item in a public folder. This example requires references to "Microsoft CDO Workflow Objects for Microsoft Exchange" (cdowf.dll) and "Microsoft CDO for Microsoft Exchange Library" (cdoex.dll) in your Microsoft® Visual Basic® project.

[Visual Basic]
Dim iPd    As CDOWF.ProcessDefinition
Dim iDsrc  As CDO.IDataSource

Set iPd = New CDOWF.ProcessDefinition
Set iDsrc = iPd

'ProcDefURL must be a valid URL to a ProcessDefinition item
iDsrc.Open ProcDefURL, _
           Nothing, _
           adModeReadWrite, _
           adFailIfNotExists

See Also

Workflow Process Definition

IProcessDefinition

IDataSource

© 2000-2001 Microsoft Corporation. All rights reserved.


ProcessInstance CoClass

Defines an object used to model a work item in a workflow process.

CLSID
CD001003-8B95-11D1-82DB-00C04FB1625D
ProgID
CDOWF.ProcessInstance
Type Library
Microsoft® CDO Workflow Objects for Microsoft Exchange
Inproc Server
CDOWF.DLL
Threading Model
Both
Although Collaboration Data Objects Workflow (CDOWF) objects are labeled BOTH, they are not in fact thread safe. CDOWF objects do not support accessing one object from many threads.

Implemented Interfaces

IProcessInstance (default)

IDataSource

Remarks

You can use the ProcessInstance object to control, record, and monitor the status of an individual workflow item. It models:

  • The state of a workflow item.
  • The workflow item's relation to e-mail posted in the workflow folder.
  • What happens when a workflow item has been in a given state too long.

It also supports data access through the IDataSource interface. You do not need to use this object explicitly unless you are writing your own workflow event sink.

Example

The following example defines two variable names for the ProcessInstance object and the IDataSource interface, creates a ProcessInstance object, gets the IDataSource interface on the ProcessInstance object, and opens the ProcessInstance item with read/write access. ProcInstanceURL must be a valid URL to a ProcessInstance in a workflow folder. This example requires references to Microsoft® CDO Workflow Objects for Microsoft Exchange (cdowf.dll) and Microsoft® CDO for Microsoft Exchange Library (cdoex.dll) in your Microsoft® Visual Basic® project.

[Visual Basic]
Dim iPd    As CDOWF.ProcessInstance
Dim iDsrc  As CDO.IDataSource

Set iPd = New CDOWF.ProcessInstance
Set iDsrc = iPd

'ProcInstanceURL must be a valid URL to a ProcessInstance item
iDsrc.Open ProcInstanceURL, _
           Nothing, _
           adModeReadWrite, _
           adFailIfNotExists

See Also

Developing Advanced Workflow Applications

IProcessInstance

IDataSource

© 2000-2001 Microsoft Corporation. All rights reserved.


PublicStoreDB CoClass

Defines an object for managing a public MDB.

CLSID
25150F24-5734-11D2-A593-00C04F990D8A
ProgID
CDOEXM.PublicStoreDB
Type Library
Microsoft® CDO for Exchange Management Library
Inproc Server
CDOEXM.DLL
Threading Model
Both

Implemented Interfaces

IPublicStoreDB

IDataSource2

Supported IDataSource2 Bindings

Data pertaining to Microsoft® Exchange 2000 Server public stores can reside in both the Microsoft® Windows® Active Directory™ and the Exchange 2000 Server. In most cases you will use the IDataSource2 interface to bind to data in Active Directory using LDAP address protocol. See Active Directory and CDOEXM for related information.

Remarks

The PublicStoreDB COM class gives you the ability to create, modify and delete public stores. With the default interface, IPublicStoreDB, you can mount, dismount or move a public store. You can also modify properties that control the public store behavior.


RecurrencePattern CoClass

Allows the user to specify how a recurring event is scheduled.

CLSID
Not applicable
ProgID
Not applicable
Type Library
Microsoft® CDO for Microsoft Exchange Library
Inproc Server
CDOEX.DLL
Threading Model
Both

Implemented Interfaces

IRecurrencePattern

Supported IDataSource Bindings

None

Remarks

A RecurrencePattern object obtains an individual pattern contained within the RecurrencePatterns collection. A RecurrencePattern object contains a set of properties used for rule specifications, such as DaysOfWeek, MonthsOfYear, and Frequency. For most recurring appointments and meetings, one pattern is sufficient; but to accommodate seasonal and time zone considerations additional patterns may be necessary.

To specify an exception, such as every Tuesday at 4 p.m. except 1/5/99, add an Exception object to an Exceptions collection.

The Appointment object's GetRecurringMaster method returns the master appointment that defines the recurring instance for that appointment.

Example

[Visual Basic]
Sub RecurringMeetingRequest()
  Dim myAppt as New CDO.Appointment
  Dim RecPat as CDO.IRecurrencePattern
  Dim iAttendee  As Attendee

  With myAppt
    .Subject = "Investment Reviews"
    .StartTime = "1/6/99 10:30AM"
    .EndTime = "1/6/99 11:30AM"
    .Location = "Skybridge Atrium"
    Set iAttendee = myAppt.Attendees.Add
    iAttendee.Address = "someone@microsoft.com"
    iAttendee.Role = cdoRequiredParticipant
    Set RecPat = .RecurrencePatterns.Add("ADD")
    RecPat.Frequency = cdoWeekly
    RecPat.Instances = 10
    .CreateRequest.Message.Send
  End With
End Sub
© 2000-2001 Microsoft Corporation. All rights reserved.


RecurrencePatterns CoClass

Defines an object used to manage a collection of RecurrencePattern objects.

CLSID
Not applicable
ProgID
Not applicable
Type Library
Microsoft® CDO for Microsoft Exchange Library
Inproc Server
CDOEX.DLL
Threading Model
Both

Implemented Interfaces

IRecurrencePatterns

Supported IDataSource Bindings

None

© 2000-2001 Microsoft Corporation. All rights reserved.


StorageGroup CoClass

Defines an object for managing groups of public or private stores.

CLSID
25150F26-5734-11D2-A593-00C04F990D8A
ProgID
CDOEXM.StorageGroup
Type Library
Microsoft CDO for Exchange Management Library
Inproc Server
CDOEXM.DLL
Threading Model
Both

Implemented Interfaces

IStorageGroup

IDataSource2

Supported IDataSource2 Bindings

Data pertaining to storage groups in Microsoft® Exchange 2000 Server can reside in both the Microsoft® Windows® Active Directory™ and the Exchange 2000 Server. In most cases you will use the IDataSource2 interface to bind to data in Active Directory using the LDAP address protocol. See Active Directory and CDOEXM for related information.

Remarks

Instances of the StorageGroup COM class give you access to information pertaining to storage groups. This information is principally held in the Windows Active Directory. The default interface on the StorageGroup object is the IStorageGroup. You can use this interface to access configuration information about the underlying Jet databases (MDBs) used in the Exchange 2000 Server public and private stores.

Example

Visual Basic

Dim StorGroup as New CDOEXM.StorageGroup

SetldapURL = 'the ldap url to the storage group in the DS
StorGroup.DataSource.Open ldapURL
StorGroup.MoveLogFiles("C:\newlogPath", 0)


StoreGuidFromURL CoClass

Retrieves the store GUID from any store item URL.

CLSID
9DA0E10D-86CE-11D1-8699-00C04FB98036
ProgID
EXOLEDB.StoreGuidFromURL
Type Library
Microsoft ExOLEDB Library
Inproc Server
EXOLEDB.DLL
Threading Model
Both

Implemented Interfaces

IStoreGuidFromURL

Remarks

See Registering for MDB-Wide Events for an example of usage.


Interfaces

The topics in this section describe the CDO for Exchange 2000 Server (CDOEX), CDO for Exchange Management (CDOEXM), and Collaboration Data Objects Workflow (CDOWF) interfaces and define their encapsulated properties and methods.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


IAddressee Interface

Provides address resolution for names and free/busy information for appointment attendees.

IID
CD000139-8B95-11D1-82DB-00C04FB1625D
Extends
IDispatch

Member Summary

Properties

Name | Type | Description
AmbiguousNames (Read-only) | [Visual Basic,VBScript]IAddressees [C++,IDL] IAddressees* | A collection of all addressees that match the ambiguous criteria used to resolve a particular addressee.
Configuration | IConfiguration IConfiguration* | A reference to a Configuration object that defines the configuration information used by the object.
ContentClass (Read-only) | [Visual Basic,VBScript]String [C++,IDL] BSTR | Returns the content class of a resolved addressee.
DataSource (Read-Only) | IDataSource [C++,IDL] IDataSource* | Reserved for future use.
DirURL (Read-only) | [Visual Basic,VBScript] String [C++,IDL] BSTR | Contains the directory URL to the resolved user object in Active Directory.
DisplayName | [Visual Basic,VBScript] String [C++,IDL] BSTR | Contains the display name of the addressee.
EmailAddress | [Visual Basic,VBScript] String [C++,IDL] BSTR | Contains the e-mail address of an addressee.
Fields (Read-Only) | [Visual Basic] ADODB.Fields [C++,IDL] Fields* | Reserved for future use.
ResolvedStatus | [Visual Basic,VBScript] cdoResolvedStatus [C++,IDL] cdoResolvedStatus | Indicates the resolution status of an addressee.

Methods

Name | Description
CheckName | Attempts to resolve an addressee directory object using the information specified in the object.
GetFreeBusy | Gets the free/busy information for a resolved attendee.
GetInterface | Returns the specified dual interface on this object.

Example

[VBScript]
<Job id="resolveaddressee">

<reference object="cdo.message"/>
<reference object="adodb.connection"/>

<script language="VBScript">

Dim iPer
Set iPer = getCurrentPersonObject_ro

Wscript.Echo "User E-Mail Address:"
wscript.echo iPer.Email

WScript.Echo "User Mailbox folder URL: "
Wscript.Echo iPer.GetInterface("IMailbox").BaseFolder

Function getCurrentPersonObject_ro()

 Dim Info
 Set Info   = CreateObject("ADSystemInfo")
 Dim InfoNT
 Set InfoNT = CreateObject("WinNTSystemInfo")
 Dim iPer
 Set iPer   = CreateObject("CDO.Person")
 Dim iAddr
 Dim iAddr2
 Set iAddr  = CreateObject("CDO.Addressee")

 iAddr.EmailAddress = LCase(InfoNT.UserName) & "@" & Info.DomainDNSName

 ' Search by binding to an LDAP server in current domain.
 If Not iAddr.CheckName("LDAP://" & Info.DomainDNSName) Then
  ' Handle Ambiguous names here
   For Each iAddr2 in iAddr.AmbiguousNames
     wscript.echo iAddr2.DisplayName
     wscript.echo iAddr2.EmailAddress
   Next
 Else

  ' Note that this is for illustration purposes only as
  ' We already have the server-less LDAP URL to the current user:
  ' "LDAP://" & Info.UserName
  ' Or,
  ' "LDAP://" & Info.DomainDNSName & "/" & Info.UserName

  Wscript.Echo "LDAP://" & Info.DomainDNSName & "/" & Info.UserName
  Wscript.Echo iAddr.DirURL

  iPer.DataSource.Open iAddr.DirURL
 End If

 Set getCurrentPersonObject_ro = iPer

End Function
</script>
</Job>
© 2000-2001 Microsoft Corporation. All rights reserved.


AmbiguousNames Property

A reference to an Addressees collection containing all addressees that match the ambiguous criteria used to resolve a particular addressee.

[Visual Basic,VBScript]
Property AmbiguousNames as IAddressees
read-only
[C++]
HRESULT get_AmbigiousNames IAddressees** pVal);
[IDL]
HRESULT [propget] AmbiguousNames([out,retval] IAddressees** pVal);

Remarks

When you attempt to resolve an addressee to an LDAP object using IAddressee.DisplayName only, there may be more than one object in the directory that matches the name. In such cases, an AmbiguousNames collection is populated with each object that matches the ambiguous criteria. For example, you may set the IAddressee::DisplayName property to "John Kelly" and call IAddressee.CheckName. There may be three directory objects that match this display name. In this case, the IAddressee.ResolvedStatus property would be equal to the cdoAmbiguous (2) enumerated value, and the IAddressee.AmbiguousNames collection would contain three Addressee objects. You could then use this information with an interactive user, prompting them to select the intended addressee from the list of the addressees.

Example

[VBScript]
<Job id="resolveaddressee">

<reference object="cdo.message"/>
<reference object="adodb.connection"/>

<script language="VBScript">

Dim iPer
Set iPer = getCurrentPersonObject_ro

Wscript.Echo "User E-Mail Address:"
wscript.echo iPer.Email

WScript.Echo "User Mailbox folder URL: "
Wscript.Echo iPer.GetInterface("IMailbox").BaseFolder

Function getCurrentPersonObject_ro()

 Dim Info
 Set Info   = CreateObject("ADSystemInfo")
 Dim InfoNT
 Set InfoNT = CreateObject("WinNTSystemInfo")
 Dim iPer
 Set iPer   = CreateObject("CDO.Person")
 Dim iAddr
 Dim iAddr2
 Set iAddr  = CreateObject("CDO.Addressee")

 iAddr.EmailAddress = LCase(InfoNT.UserName) & "@" & Info.DomainDNSName

 ' Search by binding to an LDAP server in current domain.
 If Not iAddr.CheckName("LDAP://" & Info.DomainDNSName) Then
  ' Handle Ambiguous names here
   For Each iAddr2 in iAddr.AmbiguousNames
     wscript.echo iAddr2.DisplayName
     wscript.echo iAddr2.EmailAddress
   Next
 Else

  ' Note that this is for illustration purposes only as
  ' We already have the server-less LDAP URL to the current user:
  ' "LDAP://" & Info.UserName
  ' Or,
  ' "LDAP://" & Info.DomainDNSName & "/" & Info.UserName

  Wscript.Echo "LDAP://" & Info.DomainDNSName & "/" & Info.UserName
  Wscript.Echo iAddr.DirURL

  iPer.DataSource.Open iAddr.DirURL
 End If

 Set getCurrentPersonObject_ro = iPer

End Function
</script>
</Job>
© 2000-2001 Microsoft Corporation. All rights reserved.


Configuration Property

A reference to a Configuration object used to define configuration information for the object.

[Visual Basic,VBScript]
Property Configuration as IConfiguration
[C++]
HRESULT get_Configuration(IConfiguration** pVal);
HRESULT put_Configuration(IConfiguration* Val);
[IDL]
HRESULT [propget] Configuration([out,retval] IConfiguration** pVal);
HRESULT [propput] Configuration([in] IConfiguration* Val);

Remarks

You can use this property to associate a specific instance of the Configuration COM class with the Addressee object.

Example

[Visual Basic]
Dim Config as New CDO.Configuration
Dim iAddree as New CDO.Addressee
Set iAddree.Configuration = Config
© 2000-2001 Microsoft Corporation. All rights reserved.


ContentClass Property

Returns the content class of a resolved addressee.

[Visual Basic,VBScript]
Property ContentClass as String
read-only
[C++]
HRESULT get_ContentClass(BSTR* pVal);
[IDL]
HRESULT [propget] ContentClass([out,retval] BSTR* pVal);

Remarks

The following table lists the valid values for this property.

Value | Meaning
"urn:content-classes:folder" | The addressee is an Exchange folder.
"urn:content-classes:person" | The addressee is a person.
"urn:content-classes:resource" | The addressee is a physical resource.
"" | The addressee content class is unknown.


DataSource Property

Reserved for future use.

[Visual Basic]
Property DataSource as IDataSource
read-only
[C++]
HRESULT get_DataSource(IDataSource** pVal);
[IDL]
HRESULT [propget] DataSource([out,retval] IDataSource** pVal);

Remarks

You can use the DataSource property to navigate to the IDataSource interface on the object implementing IAddressee. This is equivalent to using QueryInterface in C++ or Set in Microsoft® Visual Basic®, or using the IAddressee.GetInterface method.


DirURL Property

Contains the directory URL to the resolved user object in Active Directory.

[Visual Basic,VBScript]
Property DirURL as String
read-only
[C++]
HRESULT get_DirURL(BSTR* pVal);
[IDL]
HRESULT [propget] DirURL([out,retval] BSTR* pVal);

Remarks

This property defaults to the empty string until the addressee is resolved using the IAddressee.CheckName method. After the addressee is resolved, the DirURL property contains the directory URL to the corresponding directory object. If the search criteria were ambiguous and multiple matches occurred, the DirURL property remains empty.

Example

[VBScript]
<Job id="resolveaddressee">

<reference object="cdo.message"/>
<reference object="adodb.connection"/>

<script language="VBScript">

Dim iPer
Set iPer = getCurrentPersonObject_ro

Wscript.Echo "User E-Mail Address:"
wscript.echo iPer.Email

WScript.Echo "User Mailbox folder URL: "
Wscript.Echo iPer.GetInterface("IMailbox").BaseFolder

Function getCurrentPersonObject_ro()

 Dim Info
 Set Info   = CreateObject("ADSystemInfo")
 Dim InfoNT
 Set InfoNT = CreateObject("WinNTSystemInfo")
 Dim iPer
 Set iPer   = CreateObject("CDO.Person")
 Dim iAddr
 Dim iAddr2
 Set iAddr  = CreateObject("CDO.Addressee")

 iAddr.EmailAddress = LCase(InfoNT.UserName) & "@" & Info.DomainDNSName

 ' Search by binding to an LDAP server in current domain.
 If Not iAddr.CheckName("LDAP://" & Info.DomainDNSName) Then
  ' Handle Ambiguous names here
   For Each iAddr2 in iAddr.AmbiguousNames
     wscript.echo iAddr2.DisplayName
     wscript.echo iAddr2.EmailAddress
   Next
 Else

  ' Note that this is for illustration purposes only as
  ' We already have the server-less LDAP URL to the current user:
  ' "LDAP://" & Info.UserName
  ' Or,
  ' "LDAP://" & Info.DomainDNSName & "/" & Info.UserName

  Wscript.Echo "LDAP://" & Info.DomainDNSName & "/" & Info.UserName
  Wscript.Echo iAddr.DirURL

  iPer.DataSource.Open iAddr.DirURL
 End If

 Set getCurrentPersonObject_ro = iPer

End Function
</script>
</Job>
© 2000-2001 Microsoft Corporation. All rights reserved.


DisplayName Property

Contains the display name of the addressee.

[Visual Basic,VBScript]
Property DisplayName as String
[C++]
HRESULT get_DisplayName(BSTR* pVal);
HRESULT put_DisplayName(BSTR Val);
[IDL]
HRESULT [propget] DisplayName([out,retval] BSTR* pVal);
HRESULT [propput] DisplayName([in] BSTR Val);

Remarks

The DisplayName property defaults to the empty string until the addressee is resolved using the IAddressee.CheckName method. After the addressee is resolved, this property contains the display name of the addressee as contained in the corresponding directory object. If the search criteria were ambiguous and multiple matches occurred, the DisplayName property remains empty.

Note that you can set the DisplayName property explicitly and then call IAddressee.CheckName. The DisplayName property is then used along with other property values when attempting to resolve the addressee to a directory object.


EmailAddress Property

Contains the e-mail address of an addressee.

[Visual Basic,VBScript]
Property EmailAddress as String
[C++]
HRESULT get_EmailAddress(BSTR* pVal);
HRESULT put_EmailAddress(BSTR Val);
[IDL]
HRESULT [propget] EmailAddress([out,retval] BSTR* pVal);
HRESULT [propput] EmailAddress([in] BSTR Val);

Remarks

This property defaults to the empty string until the addressee is resolved using the IAddressee.CheckName method. After the addressee is resolved, the EmailAddress property contains the e-mail address for the addressee as defined in the corresponding directory object. If the search criteria were ambiguous and multiple matches occurred, the EmailAddress remains empty unless previously set.

Note that you can set the EmailAddress explicitly and then call IAddressee.CheckName. The EmailAddress is then used along with other property values when attempting to resolve the addressee to a directory object.


Fields Property

Reserved for future use.

[Visual Basic]
Property Fields as ADODB.Fields
read-only
[C++]
HRESULT get_Fields(Fields** pVal);
[IDL]
HRESULT [propget] Fields([out,retval] Fields** pVal);

Remarks

The Fields property obtains a collection of ADO Field objects, each of which contains a field relating to the addressee.

Note When you use the ADO Fields.Update method, field values are updated only in memory. You must call IDataSource.Save to save the changes to the Web Storage System. To get the IDataSource interface, use the GetInterface method on the CDO object.

Example

This example determines how many fields a message has:

Dim iAddr as New CDO.Addressee
Dim collFields as Fields
Set collFields = iAddr.Fields

If collFields.Count = 0 Then
  MsgBox "Fields collection is empty"
Else
  MsgBox "Message has " & collFields.Count & " fields"
End If
© 2000-2001 Microsoft Corporation. All rights reserved.


ResolvedStatus Property

Indicates the resolution status of this addressee.

[Visual Basic,VBScript]
Property ResolvedStatus as CdoResolvedStatus
[C++]
HRESULT get_ResolvedStatus(CdoResolvedStatus* pVal);
HRESULT put_ResolvedStatus(CdoResolvedStatus Val);
[IDL]
HRESULT [propget] ResolvedStatus([out,retval] CdoResolvedStatus*);
HRESULT [propput] ResolvedStatus([in] CdoResolvedStats Val);

Remarks

The Addressee object (that exposes the IAddressee interface) can be in one of three possible resolution states defined by the CdoResolvedStatus enumeration.

CdoResolvedStatus Enum

Name | Value | Description
cdoUnresolved | 0 | The addressee has not been successfully resolved, meaning that the corresponding directory object has not been identified.
cdoResolved | 1 | The addressee's directory object has successfully been located, and the addressee is considered resolved.
cdoAmbiguous | 2 | A previous attempt to resolve the addressee—that is, locate the corresponding directory object—resulted in multiple matches. The search criteria were ambiguous, and multiple directory objects that match the criteria were found and are present in the AmbiguousNames recordset.

When you first create an instance of the Addressee COM class, its state is said to be unresolved (cdoUnresolved). After you specify information such as a display name, directory URL, or e-mail address, you can call IAddressee.CheckName to attempt to resolve the addressee and thereby locate the addressee's directory object. If the object is located, and uniquely matches the specified criteria, the object enters the resolved state (cdoResolved). If multiple directory objects match the criteria, the object enters the ambiguous state (cdoAmbiguous). When in this state, the IAddressee.AmbiguousNames recordset contains information about each object that matched the criteria for the resolution attempt.


CheckName Method

Attempts to resolve an addressee directory object using the information specified in the object.

[Visual Basic,VBScript]
Function CheckName(Directory As String [, UserName As String] [, Password as String]) As Boolean
[C++]
HRESULT CheckName(BSTR Directory,
[, BSTR UserName ]
[, BSTR Password ]
VARIANT_BOOL* pVal
);
[IDL]
HRESULT CheckName([in] BSTR Directory,
[in, optional] BSTR UserName,
[in, optional] BSTR Password,
[out, retval] VARIANT_BOOL* pVal
);
Directory
The File URL or LDAP URL to use when performing the search. The File URL is used to search the Web Storage System; the LDAP URL is used to search Active Directory.
Username
Optional user name authentication.
Password
Optional password authentication.
Val
Indicates whether the check was successful.

Example

[VBScript]
<Job id="resolveaddressee">

<reference object="cdo.message"/>
<reference object="adodb.connection"/>

<script language="VBScript">

Dim iPer
Set iPer = getCurrentPersonObject_ro

Wscript.Echo "User E-Mail Address:"
wscript.echo iPer.Email

WScript.Echo "User Mailbox folder URL: "
Wscript.Echo iPer.GetInterface("IMailbox").BaseFolder

Function getCurrentPersonObject_ro()

 Dim Info
 Set Info   = CreateObject("ADSystemInfo")
 Dim InfoNT
 Set InfoNT = CreateObject("WinNTSystemInfo")
 Dim iPer
 Set iPer   = CreateObject("CDO.Person")
 Dim iAddr
 Dim iAddr2
 Set iAddr  = CreateObject("CDO.Addressee")

 iAddr.EmailAddress = LCase(InfoNT.UserName) & "@" & Info.DomainDNSName

 ' Search by binding to an LDAP server in current domain.
 If Not iAddr.CheckName("LDAP://" & Info.DomainDNSName) Then
  ' Handle Ambiguous names here
   For Each iAddr2 in iAddr.AmbiguousNames
     wscript.echo iAddr2.DisplayName
     wscript.echo iAddr2.EmailAddress
   Next
 Else

  ' Note that this is for illustration purposes only as
  ' We already have the server-less LDAP URL to the current user:
  ' "LDAP://" & Info.UserName
  ' Or,
  ' "LDAP://" & Info.DomainDNSName & "/" & Info.UserName

  Wscript.Echo "LDAP://" & Info.DomainDNSName & "/" & Info.UserName
  Wscript.Echo iAddr.DirURL

  iPer.DataSource.Open iAddr.DirURL
 End If

 Set getCurrentPersonObject_ro = iPer

End Function
</script>
</Job>
© 2000-2001 Microsoft Corporation. All rights reserved.


GetFreeBusy Method

Gets the free/busy information for a resolved addressee.

[Visual Basic,VBScript]
Function GetFreeBusy(
  StartTime As Date,
  EndTime As Date,
  Interval As Long,
  HTTPHost As String,
  Vroot As String,
  UserName As String,
  Password As String,) As String
[C++]
HRESULT GetFreeBusy(
DATE StartTime,
DATE EndTime,
long Interval,
BSTR HTTPHost,
BSTR Vroot
BSTR UserName
BSTR Password
BSTR* pbstrRet
);
[IDL]
HRESULT GetFreeBusy(
[in] DATE StartTime,
[in] DATE EndTime,
[in] long Interval,
[in, optional] BSTR HTTPHost
[in, optional] BSTR Vroot
[in, optional] BSTR UserName
[in, optional] BSTR Password
[out, retval] BSTR* pbstrRet
);
StartTime
The starting time of the range to determine free/busy status.
EndTime
The ending time of the range to determine free/busy status.
Interval
The interval, in minutes, of the free/busy time to download. Must be greater than or equal to one minute.
HTTPHost
Reserved for future use.
Vroot
Reserved for future use.
UserName
Reserved for future use.
Password
Reserved for future use.
pbstrRet [C++,IDL]
On successful return, a BSTR containing the free/busy results for the period and interval specified.

Remarks

The GetFreeBusy method returns the status for the free/busy time slots between the StartTime and EndTime parameters.


GetInterface Method

Returns the specified dual interface on this object.

[Visual Basic,VBScript]
Function GetInterface(ByVal Interface as String) as Object
[C++]
HRESULT GetInterface( BSTR Interface, IDispatch** ppUnknown);
[IDL]
HRESULT GetInterface([in] BSTR Interface, [out,retval] IDispatch** ppUnknown);
Interface
The name of the interface to obtain. The list of possible interfaces to return depends upon the COM class that provides the implementation.
ppUnknown [C++,IDL]
If the method succeeds, then on return the address passed holds a reference to the requested interface.

Remarks

The GetInterface method is primarily intended as a generic interface navigation aid to scripting languages that do not support such navigation directly.

The list of valid interface names to pass to GetInterface is dependent upon a specific implementation. As a general rule, the name of the desired interface should match the physical name of the interface as it appears in the type library or .idl file. Check the appropriate COM class for a list of exposed dual interfaces. If the object does not support the requested interface, an exception is raised with the HRESULT value of E_INVALIDARG.

Example

[VBScript]
Dim iAdrse
Set iAdrse = CreateObject("CDO.Addressee")
Dim iDsrc
Set iDsrc = iAdrse.GetInterface("IDataSource")


IAddressees Interface

Defines properties that enable access to a collection of Addressee objects. This collection is returned by the AmbiguousNames property of the IAddressee interface.

IID
CD000142-8B95-11D1-82DB-00C04FB1625D
Extends
IDispatch

Member Summary

Properties

Name | Type | Description
Count (Read-only) | [Visual Basic,VBScript]Long [C++,IDL] long | Returns the number of Addressee objects in the collection.
Item (Read-only) | [Visual Basic,VBScript] Addressee [C++,IDL] Addressee* | Returns the Addressee object specified by an index.
_NewEnum (Read-only) | [Visual Basic,VBScript] (Used in For Each In) [C++,IDL] IUnknown* | Returns an IEnumVariant interface on an enumeration object. (This property is hidden from Microsoft® Visual Basic® and is used in For Each In constructs.)

Remarks

The collection index always ranges from 1 to the value returned by the Count property.


Count Property

Returns the number of Addressee objects in the collection.

[Visual Basic,VBScript]
Property Count as Long
read-only
[C++]
HRESULT get_Count(long* pVal);
[IDL]
HRESULT [propget] Count([out,retval] long* pVal);


Item Property

Returns the Addressee object specified by an index.

[Visual Basic,VBScript]
Property Item(ByVal Index as Long) as Addressee
read-only
[C++]
HRESULT get_Item(long* Index, Addressee** pVal);
[IDL]
HRESULT [propget] Item([in] long Index, [out,retval] Addressee** pVal);

Remarks

Item is the default member on the interface. The collection index always ranges from 1 to the value returned by the Count property.


_NewEnum Property

Returns an IEnumVariant interface on an enumeration object for the collection. This property is hidden from Microsoft® Visual Basic® and Microsoft® Visual Basic® Scripting Edition (VBScript).

[Visual Basic,VBScript]
Used automatically in For Each In constructs
[C++]
HRESULT get__NewEnum(IUnknown** pVal);
[IDL]
HRESULT [propget] _NewEnum([out,retval] IUnknown** pVal);

Remarks

This property is hidden within Visual Basic and VBScript. It is a standard property used to support enumerating collections, such as the

For Each in

construct in Visual Basic.

Example

[Visual Basic]
Dim iAddr as IAddressee
Dim iAddrs as IAddressees
...
For Each iAddr in iAddrs   ' _NewEnum used internally here
...
Next iAddr
© 2000-2001 Microsoft Corporation. All rights reserved.


IAppointment Interface

Provides properties and methods for defining and manipulating appointments.

IID
CD000120-8B95-11D1-82DB-00C04FB1625D
Extends
IDispatch

Member Summary

Properties

Name | Type | Description
AllDayEvent | [Visual Basic,VBScript] Boolean [C++,IDL] VARIANT_BOOL | Specifies TRUE or FALSE, depending on whether an event is scheduled for an entire day.
Attachments (Read-only) | [Visual Basic,VBScript] IBodyParts [C++,IDL] IBodyParts* | Returns the collection of attachments in a message.
Attendees (Read-only) | [Visual Basic,VBScript] IAttendees [C++,IDL] IAttendees* | Returns the IAttendees interface on the implementing object.
BodyPart (Read-only) | [Visual Basic,VBScript] IBodyPart [C++,IDL] IBodyPart* | Returns the IBodyPart interface on the implementing object.
BusyStatus | [Visual Basic,VBScript] String [C++,IDL] BSTR | Specifies how an appointment appears in the free/busy view.
Configuration | IConfiguration IConfiguration* | A reference to a Configuration object that defines the configuration information used by the object.
Contact | [Visual Basic,VBScript] String [C++,IDL] BSTR | Contains a person's name as a contact for an appointment.
ContactURL | [Visual Basic,VBScript] String [C++,IDL] BSTR | Contains a URI for accessing an alternative format of the contact information.
DataSource (Read-only) | IDataSource [C++,IDL] IDataSource* | Returns the IDataSource interface on the object.
Duration | [Visual Basic,VBScript] Long [C++,IDL] long | Contains the duration of an appointment in seconds. Either a Duration or an EndTime is required.
EndTime | [Visual Basic,VBScript] Date [C++,IDL] DATE | Contains the time an appointment ends. Either an EndTime or a Duration is required.
Exceptions (Read-only) | IExceptions [C++,IDL] IExceptions* | Returns an IExceptions collection of exceptions for a recurring schedule of appointments.
Fields (Read-only) | [Visual Basic,VBScript] ADODB.Fields [C++,IDL] Fields* | Returns an ADO Fields interface on an ADO Fields collection object. The object contains the resource fields associated with a message.
GEOLatitude | [Visual Basic,VBScript] Long [C++,IDL] long | Contains the geographical latitude of an appointment's location.
GEOLongitude | [Visual Basic,VBScript] Long [C++,IDL] long | Contains the geographical longitude of an appointment's location.
Keywords | [Visual Basic,VBScript] Variant [C++,IDL] VARIANT | Contains keywords identifying an appointment.
Location | [Visual Basic,VBScript] String [C++,IDL] BSTR | Contains an appointment's meeting location.
LocationURL | [Visual Basic,VBScript] String [C++,IDL] BSTR | Contains a URI for accessing an alternative format of the location information.
MeetingStatus | [Visual Basic,VBScript] String [C++,IDL] BSTR | Contains the status of an appointment: Tentative, Confirmed, or Canceled.
Priority | [Visual Basic,VBScript] Long [C++,IDL] long | Contains an appointment's priority status: Normal, Urgent, or Nonurgent. The value is indicated using the CdoPriorityValues enumeration.
RecurrencePatterns (Read-only) | IRecurrencePatterns [C++,IDL] IRecurrencePatterns* | Returns an IRecurrencePatterns collection of recurring information for a recurring appointment.
ReplyTime (Read-only) | [Visual Basic,VBScript] Date [C++,IDL] DATE | Returns the time a recipient replied to a meeting request.
Resources | [Visual Basic,VBScript] String [C++,IDL] BSTR | Contains a list of supportive resources for an appointment.
ResponseRequested | [Visual Basic,VBScript] Boolean [C++,IDL] VARIANT_BOOL | Indicates if a response is requested for an appointment.
Sensitivity | [Visual Basic,VBScript] Long [C++,IDL] long | Contains the status of an appointment's sensitivity: Company-Confidential, Personal, or Private. The value is indicated using the CdoSensitivityValues enumeration.
StartTime | [Visual Basic,VBScript] Date [C++,IDL] DATE | Contains the starting time for an appointment. StartTime is a required property.
Subject | [Visual Basic,VBScript] String [C++,IDL] BSTR | Contains the topic for an appointment.
TextBody | [Visual Basic,VBScript] String [C++,IDL] BSTR | Contains the decoded text description of the appointment.
Transparent | [Visual Basic,VBScript] String [C++,IDL] BSTR | Contains whether an appointment appears in the free/busy string.

Methods

Name | Description
Accept | Prepares and returns a CalendarMessage object for accepting a meeting request.
AcceptTentative | Prepares and returns a CalendarMessage object for tentatively accepting a meeting request.
Cancel | Prepares and returns a CalendarMessage object for canceling a meeting request.
CreateRequest | Prepares and returns a CalendarMessage object for sending a meeting request.
Decline | Prepares and returns a CalendarMessage object for declining a meeting request.
GetFirstInstance | Returns the first instance of a recurring appointment.
GetInterface | Returns a specified interface on this object. Acts as a QueryInterface or Set method for scripting languages.
GetNextInstance | Returns the next instance of a recurring appointment.
GetRecurringMaster | Returns the master recurring appointment for an exception or instance of the master appointment.
Invite | Forwards the appointment to another recipient.
Publish | Writes the appointment information for other users to a file or URL.


AllDayEvent Property

Specifies TRUE or FALSE, depending on whether an event is scheduled for an entire day.

[Visual Basic,VBScript]
Property AllDayEvent As Boolean
[C++]
HRESULT get_AllDayEvent(VARIANT_BOOL* pVal);
HRESULT put_AllDayEvent(VARIANT_BOOL pVal);
[IDL]
HRESULT [propget] AllDayEvent([out,retval] VARIANT_BOOL* pVal);
HRESULT [proput] AllDayEvent([in] VARIANT_BOOL Val);

Remarks

Setting the AllDayEvent property does not affect the start time or end time of an appointment or meeting. This property is also available as the schema field alldayevent.


Attachments Property

Returns the collection of attachments in a message.

[Visual Basic,VBScript]
Property Attachments As IBodyParts
read-only
[C++]
HRESULT get_Attachments(IBodyParts** pVal);
[IDL]
HRESULT [propget] Attachments([out,retval] IBodyParts** pVal);

Remarks

Attachments are stored as body parts in a message's MIME hierarchy. The Attachments property returns a collection of objects that expose the IBodyPart interface, each of which is deemed to be an attachment by the implementing COM class. In most cases, attachments are flagged as such by setting the MIME header Content-Disposition to "attachment." However, a given body part's status as an attachment is implementation-dependent.

For more information on body parts and MIME structures, see Creating MIME-Formatted Messages.

Example

The following code determines the number of attachments in a message:

[Visual Basic]
Dim iMsg As New CDO.Message ' message to be inspected
Dim collAtts As CDO.IBodyParts ' attachments collection of message
' ... assume message is valid ...
Set collAtts = iMsg.Attachments ' see if there is a collection

If collAtts.Count = 0 Then
  MsgBox "Attachments collection exists but is empty"
Else
  MsgBox "Message has " & collAtts.Count & " attachments"
End If
© 2000-2001 Microsoft Corporation. All rights reserved.


Attendees Property

Returns the IAttendees interface on the implementing object.

[Visual Basic,VBScript]
Property Attendees As IAttendees
read-only
[C++]
HRESULT get_Attendees(IAttendees** pVal);
[IDL]
HRESULT [propget] Attendees ([out,retval] IAttendees** pVal);


BodyPart Property

Returns the IBodyPart interface on the implementing object.

[Visual Basic,VBScript]
Property BodyPart As IBodyPart
read-only
[C++]
HRESULT get_BodyPart(IBodyPart** pVal);
[IDL]
HRESULT [propget] BodyPart([out,retval] IBodyPart** pVal);


BusyStatus Property

Specifies how an appointment appears in the free/busy view.

Note that when there is more than one appointment during an interval, the free/busy status returned is the highest status for that interval. The status values ranked from highest to lowest are OOF, Busy, Tentative, and Free.

For more information about using free/busy information, see Checking Free/Busy Status.

[Visual Basic,VBScript]
Property BusyStatus As String
[C++]
HRESULT get_BusyStatus(BSTR* pVal);
HRESULT put_BusyStatus(BSTR Val);
[IDL]
HRESULT [propget] BusyStatus([out,retval] BSTR* pVal);
HRESULT [proput] BusyStatus([in] BSTR Val);

Remarks

Use the following constant values in CdoBusyStatusValues:

Constant | Value
cdoBusy | Busy
cdoFree | Free
cdoOOF | OOF
cdoTentative | Tentative

This property is also available as the schema field busystatus.


Configuration Property

Contains a Configuration object reference. This object defines the messaging configuration used by the Message object.

[Visual Basic,VBScript]
Property Configuration As IConfiguration
[C++]
HRESULT get_Configuration(IConfiguration** pVal);
HRESULT put_Configuration(IConfiguration* Val);
[IDL]
HRESULT [propget] Configuration([out,retval] IConfiguration** pVal);
HRESULT [propput] Configuration([in] IConfiguration* Val);


Contact Property

Contains a person's name as a contact for an appointment.

[Visual Basic,VBScript]
Property Contact As String
[C++]
HRESULT get_Contact(BSTR* pVal);
HRESULT put_Contact(BSTR Val);
[IDL]
HRESULT [propget] Contact([out,retval] BSTR* pVal);
HRESULT [proput] Contact([in] BSTR Val);


ContactURL Property

Contains a URL for accessing an alternative format of the contact information.

[Visual Basic,VBScript]
Property ContactURL As String
[C++]
HRESULT get_ContactURL(BSTR* pVal);
HRESULT put_ContactURL(BSTR Val);
[IDL]
HRESULT [propget] ContactURL([out,retval] BSTR* pVal);
HRESULT [proput] ContactURL([in] BSTR Val);

Remarks

The ContactURL property corresponds to the ICAL CONTACT parameter, which is defined as a Uniform Resource Identifier (URI). A URI can only be made up of US-ASCII characters. CDO assumes that this property is always made up of US-ASCII characters, and no character encoding conversions are performed.


DataSource Property

Returns the IDataSource interface on the implementing object.

[Visual Basic,VBScript]
Property DataSource As IDataSource
read-only
[C++]
HRESULT get_DataSource(IDataSource** pVal);
[IDL]
HRESULT [propget] DataSource([out,retval] IDataSource** pVal);

Remarks

The DataSource property returns the IDataSource interface on the object. You can use the IDataSource interface to open and save items in the store.

If the object does not implement the IDataSource interface, the COM exception E_NOTIMPL is raised.


Duration Property

Contains the duration of an appointment in seconds.

Either a Duration or an EndTime is required. Duration must be greater than or equal to zero if specified. If EndTime is specified, Duration is ignored.

[Visual Basic,VBScript]
Property Duration As Long
[C++]
HRESULT get_Duration(long* pVal);
HRESULT put_Duration(long Val);
[IDL]
HRESULT [propget] Duration([out,retval] long* pVal);
HRESULT [proput] Duration([in] long Val);

Remarks

This property is also available as the schema field duration.


EndTime Property

Contains the time an appointment ends.

Either a Duration or an EndTime is required. EndTime must be greater than or equal to the StartTime. If EndTime is specified, Duration is ignored.

[Visual Basic,VBScript]
Property EndTime As Date
[C++]
HRESULT get_EndTime(DATE* pVal);
HRESULT put_EndTime(DATE Val);
[IDL]
HRESULT [propget] EndTime([out,retval] DATE* pVal);
HRESULT [proput] EndTime([in] DATE Val);

Remarks

This property is also available as the schema field dtend.


Exceptions Property

Returns an IExceptions collection of exceptions for a recurring schedule of appointments.

[Visual Basic,VBScript]
Property Exceptions As IExceptions
read-only
[C++]
HRESULT get_Exceptions(IExceptions** pVal);
[IDL]
HRESULT [propget] Exceptions([out,retval] IExceptions** pVal);


Fields Property

Returns an ADO Fields interface on an ADO Fields collection object. The object contains the resource fields associated with a message.

[Visual Basic,VBScript]
Property Fields As ADODB.Fields
read-only
[C++]
HRESULT get_Fields(Fields** pVal);
[IDL]
HRESULT [propget] Fields([out,retval] Fields** pVal);

Remarks

The ADO Fields object is a collection of ADO Field objects that pertain to this object. Each Field object holds a name/value pair defining some header field for the body part. The name is always a string, and the value is a VARIANT. The subtype of the VARIANT depends on the schema definition for the name. See the appropriate schema fields section of the reference for a list of valid fields to use, along with a list of the VARIANT subtypes for each field.

The fields that resize in this collection depend upon the specific implementation. Consult the appropriate COM class for details about available fields.

Note When you use the ADO Fields.Update method, field values are updated only in memory. You must call IDataSource.Save to save the changes to the Web Storage System. To get the IDataSource interface, use the GetInterface method on the CDO object. This code is shown in the following example.

Example

[Visual Basic]
Dim myAppt As New Appointment
Dim Flds As ADODB.Fields
Set Flds = myAppt.Fields

With Flds
.Item("xxx") = "zzz"
.Update
End With

'Save the fields to the Web Storage System
Dim iDsrc As CDO.IDataSource
Set iDsrc = myAppt.GetInterface("IDataSource")
iDsrc.Save


GEOLatitude Property

Contains the geographical latitude of an appointment's location.

[Visual Basic,VBScript]
Property GEOLatitude As Long
[C++]
HRESULT get_GEOLatitude (long* pVal);
HRESULT put_GEOLatitude (long Val);
[IDL]
HRESULT [propget]GEOLatitude ([out,retval] long* pVal);
HRESULT [proput]GEOLatitude ([in] long Val);

Remarks

Positive values from 0 to 90 are degrees north latitude. Negative values from 0 to -90 are degrees south latitude.

You must set both GEOLatitude and GEOLongitude for this property to be saved. If you only set one of these two properties, the value is not saved.

This property is also available as the schema field geolatitude.


GEOLongitude Property

Contains the geographical longitude of an appointment's location.

[Visual Basic,VBScript]
Property GEOLogitude As Long
[C++]
HRESULT get_GEOLogitude(long* pVal);
HRESULT put_GEOLogitude(long Val);
[IDL]
HRESULT [propget] GEOLogitude ([out,retval] long* pVal);
HRESULT [proput] GEOLogitude ([in] long Val);

Remarks

Positive values from 0 to 180 are degrees east longitude. Negative values from 0 to -180 are degrees west longitude.

You must set both GEOLatitude and GEOLongitude for this property to be saved. If you only set one of these two properties, the value is not saved.

This property is also available as the schema field geolongitude.


Keywords Property

Contains keywords identifying an appointment.

[Visual Basic,VBScript]
Property Keywords As Variant
[C++]
HRESULT get_Keywords(VARIANT * pVal);
HRESULT put_Keywords(VARIANT Val);
[IDL]
HRESULT [propget] Keywords([out,retval] VARIANT* pVal);
HRESULT [proput] Keywords([in] VARIANT Val);

Remarks

This property is also available as the schema field keywords.


Location Property

Contains an appointment's meeting location.

[Visual Basic,VBScript]
Property Location As String
[C++]
HRESULT get_Location(BSTR* pVal);
HRESULT put_Location(BSTR Val);
[IDL]
HRESULT [propget] Location([out,retval] BSTR* pVal);
HRESULT [proput] Location([in] BSTR Val);

Remarks

This property is also available as the schema field location.


LocationURL Property

Contains a URL for accessing an alternative format of the location information.

[Visual Basic,VBScript]
Property LocationURL As String
[C++]
HRESULT get_LocationURL(BSTR* pVal);
HRESULT put_LocationURL(BSTR Val);
[IDL]
HRESULT [propget] LocationURL([out,retval] BSTR* pVal);
HRESULT [proput] LocationURL([in] BSTR Val);

Remarks

This property is also available as the schema field urn:schemas:calendar:locationurl.

The LocationURL property corresponds to the ICAL LOCATION parameter, which is defined as a Uniform Resource Identifier (URI). A URI can only be made up of US-ASCII characters. CDO assumes that this property is always made up of US-ASCII characters, and no character encoding conversions are performed.


MeetingStatus Property

Contains the status of an appointment: Tentative, Confirmed, or Canceled.

[Visual Basic,VBScript]
Property MeetingStatus As String
[C++]
HRESULT get_MeetingStatus(BSTR* pVal);
HRESULT put_MeetingStatus(BSTR Val);
[IDL]
HRESULT [propget] MeetingStatus([out,retval] BSTR* pVal);
HRESULT [proput] MeetingStatus([in] BSTR Val);

Remarks

Use the following constant values in CdoMeetingStatusValues:

Constant | Value
cdoMeetingStatusCancelled | Canceled
cdoMeetingStatusConfirmed | Confirmed
cdoMeetingStatusTentative | Tentative

This property is also available as the schema field meetingstatus.


Priority Property

Contains the appointment's priority status: Normal, Urgent, or Nonurgent.

[Visual Basic,VBScript]
Property Priority As Long
[C++]
HRESULT get_Priority(long* pVal);
HRESULT put_Priority(long Val);
[IDL]
HRESULT [propget] Priority([out,retval] long* pVal);
HRESULT [proput] Priority([in] long Val);

Remarks

The priority is indicated using values from the cdoPriorityValues enumeration.

For received ICalendar meeting requests, values less than 5 are converted to Urgent, 5 is converted to Normal, and values greater than 5 are converted to Nonurgent. For sending ICalendar meeting requests, Urgent is converted to 1, Normal is converted to 5, and Nonurgent is converted to 9.


RecurrencePatterns Property

Returns an IRecurrencePatterns collection of recurring information for a recurring appointment.

[Visual Basic,VBScript]
Property RecurrencePatterns As IRecurrencePatterns
read-only
[C++]
HRESULT get_RecurrencePatterns(IRecurrencePatterns** pVal);
[IDL]
HRESULT [propget] RecurrencePatterns([out,retval] IRecurrencePatterns** pVal);


ReplyTime Property

Returns the time a recipient replied to a meeting request.

This value is updated by CDO when the IAppointment::Accept, IAppointment::AcceptTentative, or IAppointment::Decline method is called. This value can be used to determine which response is the most recent if an attendee sends more than one response to a meeting request.

[Visual Basic,VBScript]
Property ReplyTime As Date
read-only
[C++]
HRESULT get_ReplyTime(DATE* pVal);
[IDL]
HRESULT [propget] ReplyTime([out,retval] DATE* pVal);

Remarks

This property is also available as the schema field replytime.


Resources Property

Contains a list of supportive resources for the appointment. The resources are represented as mailto URIs and are separated by commas—for example, "conf42@microsoft.com, video1@microsoft.com".

[Visual Basic,VBScript]
Property Resources As String
[C++]
HRESULT get_Resources(BSTR* pVal);
HRESULT put_Resources(BSTR Val);
[IDL]
HRESULT [propget] Resources([out,retval] BSTR* pVal);
HRESULT [proput] Resources([in] BSTR Val);

Remarks

This property is also available as the schema field resources.


ResponseRequested Property

Indicates whether a response is requested for an appointment.

[Visual Basic,VBScript]
Property ResponseRequested As Boolean
[C++]
HRESULT get_ResponseRequested(VARIANT_BOOL* pVal);
HRESULT put_ResponseRequested(VARIANT_BOOL Val);
[IDL]
HRESULT [propget] ResponseRequested([out,retval] VARIANT_BOOL* pVal);
HRESULT [proput] ResponseRequested([in] VARIANT_BOOL Val);

Remarks

Returns TRUE if a response is requested.

For outgoing meeting requests, if ResponseRequested is TRUE, the ICalendar RSVP property of all attendees is set to TRUE; if ResponseRequested is FALSE, the RSVP property of all attendees is set to FALSE. For incoming meeting requests, if the ICalendar RSVP property of any attendee is TRUE, then ResponseRequested is set to TRUE; if RSVP for all attendees is FALSE, then ResponseRequested is set to FALSE.

The ResponseRequested property is set to FALSE if the meeting does not have an organizer. The organizer is an attendee with the IsOrganizer property set to TRUE.

This property is also available as the schema field responserequested.


Sensitivity Property

Contains the status for an appointment's sensitivity: Company-Confidential, Personal, or Private.

[Visual Basic,VBScript]
Property Sensitivity As Long
[C++]
HRESULT get_Sensitivity(long* pVal);
HRESULT put_Sensitivity(long Val);
[IDL]
HRESULT [propget] Sensitivity([out,retval] long* pVal);
HRESULT [proput] Sensitivity([in] long Val);

Remarks

The sensitivity is indicated using values from the cdoSensitivityValues enumeration.


StartTime Property

Contains the starting time for an appointment.

[Visual Basic,VBScript]
Property StartTime As Date
[C++]
HRESULT get_StartTime(DATE* pVal);
HRESULT put_StartTime(DATE Val);
[IDL]
HRESULT [propget] StartTime([out,retval] Date* pVal);
HRESULT [proput] StartTime([in] BSTR Val);

Remarks

An appointment must have a start time. You can optionally specify either an EndTime or a Duration.

This property is also available as the schema field dtstart.


Subject Property

Contains the topic for the appointment.

[Visual Basic,VBScript]
Property Subject As String
[C++]
HRESULT get_Subject(BSTR* pVal);
HRESULT put_Subject(BSTR Val);
[IDL]
HRESULT [propget] Subject([out,retval] BSTR* pVal);
HRESULT [proput] Subject([in] BSTR Val);


TextBody Property

Contains the decoded text description of the appointment.

[Visual Basic,VBScript]
Property Description As String
[C++]
HRESULT get_Description(BSTR* pVal);
HRESULT put_Description(BSTR Val);
[IDL]
HRESULT [propget] Description([out,retval] BSTR* pVal);
HRESULT [proput] Description([in] BSTR Val);

Remarks

This property is sent as the Description property in ICalendar meeting requests and updates. This property is sent as the last Comment property in ICalendar meeting responses.

This property is also available as the schema field textdescription.


Transparent Property

Contains whether the appointment appears in the free/busy string returned by the GetFreeBusy method of the Addressee object. If the value of the Transparent property is "Transparent," the appointment does not appear in the free/busy string.

For more information about using free/busy information, see Checking Free/Busy Status.

[Visual Basic,VBScript]
Property Transparent As String
[C++]
HRESULT get_Transparent(BSTR* pVal);
HRESULT put_Transparent(BSTR Val);
[IDL]
HRESULT [propget] Transparent([out,retval] BSTR* pVal);
HRESULT [proput] Transparent([in] BSTR Val);

Remarks

Use the following constant values from CdoTranspValues.

Constant | Value
cdoOpaque | Opaque
cdoTransparent | Transparent

This property is also available in the Fields collection as the urn:schemas:calendar:transparent field.


Accept Method

Prepares and returns a CalendarMessage object for accepting a meeting request.

[Visual Basic,VBScript]
Function Accept() As ICalendarMessage
[C++]
HRESULT Accept(ICalendarMessage** pVal);
[IDL]
HRESULT Accept([out,retval] ICalendarMessage** pVal);


AcceptTentative Method

Prepares and returns a CalendarMessage object for tentatively accepting a meeting request.

[Visual Basic,VBScript]
Function AcceptTentative() As ICalendarMessage
[C++]
HRESULT AcceptTentative(ICalendarMessage** pVal);
[IDL]
HRESULT AcceptTentative([out,retval] ICalendarMessage** pVal);


Cancel Method

Prepares and returns a CalendarMessage object for canceling a meeting. You can also remove specific attendees without canceling the entire meeting.

[Visual Basic,VBScript]
Function Cancel(
  [EmailList As String],
  [CleanupCalendar As Boolean],
  [UserName As String],
  [Password As String]
  ) As ICalendarMessage
[C++]
HRESULT Cancel(
  [BSTR EmailList,]
  [VARIANT_BOOL CleanupCalendar,]
  [BSTR UserName,]
  [BSTR Password,]
  ICalendarMessage** pVal);
[IDL]
HRESULT Cancel(
  [in, optional] BSTR EmailList,
  [in, optional] VARIANT_BOOL CleanupCalendar
  [in, optional] BSTR UserName
  [in, optional] BSTR Password
  [out,retval] ICalendarMessage** pVal
);
EmailList
The EmailList value is a single string of attendees' e-mail addresses, separated by commas. For example:
"someone@microsoft.com,another@microsoft.com"
CleanupCalendar
When TRUE, the meeting being canceled is deleted from the calendar folder. When FALSE, the meeting is marked canceled but is not actually deleted.
UserName
The user name of the owner of the calendar.
Password
The password of the owner of the calendar.

Remarks

You can only call this method if you have previously called the CreateRequest method.

To cancel the appointment for all attendees, specify the EmailList value as an empty string (string = "").

The UserName and Password parameters are only required if you have not been authenticated as the calendar owner.


CreateRequest Method

Prepares and returns a CalendarMessage object for sending a meeting request.

[Visual Basic,VBScript]
Function CreateRequest() As ICalendarMessage
[C++]
HRESULT CreateRequest(ICalendarMessage** pVal);
[IDL]
HRESULT CreateRequest([out,retval] ICalendarMessage** pVal);


Decline Method

Prepares and returns a CalendarMessage object for declining a meeting request.

[Visual Basic,VBScript]
Function Decline(
  [CleanupCalendar As Boolean],
  [UserName As String],
  [Password As String]
  ) As ICalendarMessage
[C++]
HRESULT Decline(
  [VARIANT_BOOL CleanupCalendar,]
  [BSTR UserName,]
  [BSTR Password,]
  ICalendarMessage** pVal);
[IDL]
HRESULT Decline(
  [in, optional] VARIANT_BOOL CleanupCalendar
  [in, optional] BSTR UserName
  [in, optional] BSTR Password
  [out,retval] ICalendarMessage** pVal);
CleanupCalendar
When TRUE, the meeting being canceled is deleted from the calendar folder. When FALSE, the meeting is marked canceled but is not actually deleted.
UserName
The user name of the owner of the calendar. This value is required when CleanupCalendar is TRUE.
Password
The password of the owner of the calendar. This value is required when CleanupCalendar is TRUE.


GetFirstInstance Method

Returns the first instance of a recurring appointment.

[Visual Basic,VBScript]
Function GetFirstInstance(ByVal Start As Date, ByVal End As Date) As IAppointment
[C++]
HRESULT GetFirstInstance(DATE Start, DATE End, IAppointment** pVal);
[IDL]
HRESULT GetFirstInstance([in] DATE Start, [in] DATE End, [out,retval] IAppointment** pVal);
Start
The starting date for a range in which to determine the first instance of a recurring appointment.
End
The ending date for a range in which to determine the first instance of a recurring appointment.

Remarks

The range calculated by GetFirstInstance starts with the date and time of the first instance. It does not accommodate subsequent changes to the start time for that appointment. For example, if you set the start instance in GetFirstInstance to 3/10/2000 10 am, and later modify that appointment to start at 3/10/2000 2 pm, the GetFirstInstance range remains with the first instance at 3/10/2000 10 am.


GetInterface Method

Returns the specified dual interface on the object.

[Visual Basic,VBScript]
Function GetInterface(ByVal Interface as String) as Object
[C++]
HRESULT GetInterface( BSTR Interface, IDispatch** ppUnknown);
[IDL]
HRESULT GetInterface([in] BSTR Interface, [out,retval] IDispatch** ppUnknown);
Interface
The name of the interface to obtain. The list of possible interfaces to return depends upon the COM class that provides the implementation.
ppUnknown [C++,IDL]
If the method succeeds, then on return, the address passed holds a reference to the requested interface.

Remarks

The GetInterface method is primarily intended as a generic interface navigation aid to scripting languages that do not support such navigation directly. Most COM classes that provide implementations of the IMessage interface expose additional dual interfaces that are accessible by scripting languages only through properties on the interface, such as BodyPart and DataSource, or through using the GetInterface method. When properties do not exist on the interface to return these interfaces, the GetInterface method must be used.

The list of valid interface names to pass to GetInterface is dependent upon a specific implementation. As a general rule, the name of the desired interface should match the physical name of the interface as it appears in the type library or .idl file. Check the appropriate COM class for a list of exposed dual interfaces. If the object does not support the requested interface, an exception is raised with the HRESULT value of E_INVALIDARG.

Example

[VBScript]
Dim iApt
Set iApt = CreateObject("CDO.Appointment")
Dim iDsrc
Set iDsrc = iApt.GetInterface("IDataSource")


GetNextInstance Method

Returns the next instance of a recurring appointment based on the start and end times from the GetFirstInstance method. Returns the first instance of a recurring appointment if not preceded by GetFirstInstance or another call to GetNextInstance.

[Visual Basic,VBScript]
Function GetNextInstance() As IAppointment
[C++]
HRESULT GetNextInstance(IAppointment** pVal);
[IDL]
HRESULT GetNextInstance([out,retval] IAppointment** pVal);


GetRecurringMaster Method

Returns the master recurring appointment for an exception or instance of the master appointment.

[Visual Basic,VBScript]
Function GetRecurringMaster(
  [CalendarLocation as String],
  [UserName as String],
  [Password as String]
  ) As IAppointment
[C++]
HRESULT GetRecurringMaster(
  BSTR CalendarLocation,
  BSTR UserName,
  BSTR Password,
  IAppointment** pVal
  );
[IDL]
HRESULT GetRecurringMaster(
  [in,optional]BSTR CalendarLocation,
  [in,optional]BSTR UserName,
  [in,optional]BSTR Password,
  [out,retval] IAppointment** pVal);
CalendarLocation
The location of the calendar folder.
UserName
A user who has read/write permission to the folder specified by the CalendarLocation parameter.
Password
The user's password.

Remarks

For calendar folders in the private store, the format of the CalendarLocation string is:

"file://./backofficestorage/<domain_name>/<private_store>/<user_name>/calendar/"

If the calendar location is not specified in the method parameters, CDO uses the calendar location from the Configuration object. The following code sets the calendar location field in the Configuration object:

[Visual Basic]
Dim Config    As New Configuration
Config.Fields("CalendarLocation") = "file://./backofficestorage/domain/MBX/user/calendar"
Config.Fields.Update

Note These examples use a file URL with the Exchange OLE DB (ExOLEDB) provider. The ExOLEDB provider also supports the HTTP URL scheme.


Invite Method

Returns a calendar message used to forward the appointment to another recipient.

[Visual Basic,VBScript]
Function Invite(ByVal EmailList As String) As ICalendarMessage
[C++]
HRESULT Invite(BSTR EmailList, ICalendarMessage** pVal);
[IDL]
HRESULT Invite([in] BSTR EmailList, [out,retval] ICalendarMessage** pVal);
EmailList
A list of recipient e-mail names.

Remarks

If the organizer of the appointment calls the Invite method, the new recipients are added to the Attendees collection of the appointment. If an attendee calls the Invite method, the new recipients are not added to the Attendees collection. However, new recipients are added to the Attendees collection when they send an acceptance to the meeting organizer.

Example

[Visual Basic]
Dim iCalMsg As New CalendarMessage
Dim iAppt    As New Appointment
…
iCalMsg = iAppt.Invite ("someone@microsoft.com,another@microsoft.com")
iCalMsg.Message.Send


Publish Method

Returns a calendar message for the appointment with the method value set to "Publish." Published appointments do not have attendees. To send the calendar message, you need to add recipients using the IMessage interface of the calendar message.

[Visual Basic,VBScript]
Function Publish() As ICalendarMessage
[C++]
HRESULT Publish(ICalendarMessage** pVal);
[IDL]
HRESULT Publish([out,retval] ICalendarMessage** pVal);


IAttendee Interface

Provides properties and methods for defining and manipulating appointment attendees.

IID
CD000135-8B95-11D1-82DB-00C04FB1625D
Extends
IDispatch

Member Summary

Properties

Name | Type | Description
Address | [Visual Basic,VBScript] String [C++,IDL] BSTR | Specifies the e-mail address of an attendee.
DisplayName | [Visual Basic,VBScript] String [C++,IDL] BSTR | Specifies the display name of an attendee.
IsOrganizer | [Visual Basic,VBScript] Boolean [C++,IDL] VARIANT_BOOL | Specifies whether an attendee is the organizer of an appointment.
Role | [Visual Basic,VBScript] CdoAttendeeRoleValues [C++,IDL] CdoAttendeeRoleValues | Specifies whether an attendee is optional, required, or the meeting chair.
Status | [Visual Basic,VBScript] CdoAttendeeStatusValues [C++,IDL] CdoAttendeeStatusValues | Specifies whether an attendee has accepted, declined, or delegated an appointment.
Type | [Visual Basic,VBScript] String [C++,IDL] BSTR | Specifies the type of calendar user, such as Individual, Group, or Room.


Address Property

Specifies the e-mail address of an attendee.

[Visual Basic,VBScript]
Property Address As String
[C++]
HRESULT get_Address(BSTR* pVal);
HRESULT put_Address(BSTR Val);
[IDL]
HRESULT [propget] Address([out,retval] BSTR* pVal);
HRESULT [proput] Address([in] BSTR Val);


DisplayName Property

Specifies the display name of an attendee.

[Visual Basic,VBScript]
Property DisplayName As String
[C++]
HRESULT get_DisplayName(BSTR* pVal);
HRESULT put_DisplayName(BSTR Val);
[IDL]
HRESULT [propget] DisplayName([out,retval] BSTR* pVal);
HRESULT [proput] DisplayName([in] BSTR Val);


IsOrganizer Property

Specifies whether an attendee is the organizer of an appointment. By default, CDO sets this value to TRUE for the attendee who creates the appointment.

[Visual Basic,VBScript]
Property IsOrganizer As Boolean
[C++]
HRESULT get_IsOrganizer(VARIANT_BOOL* pVal);
HRESULT put_IsOrganizer(VARIANT_BOOL Val);
[IDL]
HRESULT [propget] IsOrganizer([out,retval] VARIANT_BOOL* pVal);
HRESULT [propput] IsOrganizer([in] VARIANT_BOOL Val);

Remarks

Set to TRUE if an attendee is the organizer.

An appointment can have only one organizer. CDO returns CDO_E_BAD_ATTENDEE_DATA if it detects more than one attendee with IsOrganizer set to TRUE when creating or modifying an appointment.


Role Property

Specifies whether an attendee is optional, required, or the meeting chair.

[Visual Basic,VBScript]
Property Role As CdoAttendeeRoleValues
[C++]
HRESULT get_Role(CdoAttendeeRoleValues* pVal);
HRESULT put_Role(CdoAttendeeRoleValues Val);
[IDL]
HRESULT [propget] Role([out,retval] CdoAttendeeRoleValues* pVal);
HRESULT [proput] Role([in] CdoAttendeeRoleValues Val);

Remarks

Use the CdoAttendeeRoleValues enumeration to set the value for this property.


Status Property

Specifies whether an attendee has accepted, declined, or delegated an appointment.

[Visual Basic,VBScript]
Property Status As CdoAttendeeStatusValues
[C++]
HRESULT get_Status(CdoAttendeeStatusValues* pVal);
HRESULT put_Status(CdoAttendeeStatusValues Val);
[IDL]
HRESULT [propget] Status([out,retval] CdoAttendeeStatusValues* pVal);
HRESULT [proput] Status([in] CdoAttendeeStatusValues Val);

Remarks

Use the CdoAttendeeStatusValues enumeration to set the value for this property.


Type Property

Specifies the type of calendar user.

[Visual Basic,VBScript]
Property Type As String
[C++]
HRESULT get_Type(BSTR* pVal);
HRESULT put_Type(BSTR Val);
[IDL]
HRESULT [propget] Type([out,retval] BSTR* pVal);
HRESULT [proput] Type([in] BSTR Val);

Remarks

The valid values are "Individual," "Resource," "Group," "Room," "Unknown," or an X-token.


IAttendees Interface

Defines properties and methods that enable access to a collection of Attendee COM objects.

IID
CD000136-8B95-11D1-82DB-00C04FB1625D
Extends
IDispatch

Member Summary

Properties

Name | Type | Description
Count (Read-only) | [Visual Basic,VBScript]Long [C++,IDL] long | Returns the number of Attendee objects in the collection.
Item (Read-only) | [Visual Basic,VBScript] Attendee [C++,IDL] IAttendee* | Returns the Attendee object specified by the index.
_NewEnum (Read-only) | [Visual Basic,VBScript] (Used in For Each In) [C++,IDL] IUnknown* | Returns an IEnumVariant interface on an enumeration object. (This property is hidden from Microsoft® Visual Basic® and is used in For EachIin constructs.)

Methods

Name | Description
Add | Adds an Attendee object to the collection.
Delete | Removes the specified Attendee object from the collection.

Remarks

The collection index always ranges from 1 to the value returned by the Count property.


Count Property

Returns the number of Attendee objects in the collection.

[Visual Basic,VBScript]
Property Count as Long
read-only
[C++]
HRESULT get_Count(long* pVal);
[IDL]
HRESULT [propget] Count([out,retval] long* pVal);


Item Property

Returns the Attendee object specified by the index.

[Visual Basic,VBScript]
Property Item(ByVal Index as Long) as CDO.Attendee
read-only
[C++]
HRESULT get_Item(long* Index, IAttendee** pVal);
[IDL]
HRESULT [propget] Item([in] long Index, [out,retval] IAttendee** pVal);

Remarks

Item is the default member on the interface. The collection index always ranges from 1 to the value returned by the Count property.


_NewEnum Property

Returns an IEnumVariant interface on an enumeration object for the collection. This property is hidden from Microsoft® Visual Basic® and Microsoft® Visual Basic® Scripting Edition (VBScript).

[Visual Basic,VBScript]
Used automatically in For Each In constructs
[C++]
HRESULT get__NewEnum(IUnknown** pVal);
[IDL]
HRESULT [propget] _NewEnum([out,retval] IUnknown** pVal);

Remarks

This property is hidden within Visual Basic and VBScript. It is a standard property used to support enumerating collections, such as the

For Each in

construct in Visual Basic.

Example

[Visual Basic]
Dim iAtnd as IAttendee
Dim iAtnds as IAttendees
...
For Each iAtnd in iAtnds   ' _NewEnum used internally here
...
Next iAtnd
© 2000-2001 Microsoft Corporation. All rights reserved.


Add Method

Adds a new Attendee object to the collection.

[Visual Basic,VBScript]
Sub Add([Address As String]) As CDO.Attendee
[C++]
HRESULT Add([BSTR Address,] IAttendee** pVal);
[IDL]
HRESULT Add(
   [in,optional] BSTR Address,
   [out,retval] IAttendee** pVal);
Address
The optional SMTP address of the attendee being added.

Remarks

By specifying the SMTP address of the attendee in the Add method, you can add an attendee with a single line of code. The attendee is added as a required participant. For example:

iAppt.Attendees.Add("someone@microsoft.com")

Is equivalent to:

Set Atnd = iAppt.Attendees.Add
Atnd.Address = "someone@microsoft.com"
Atnd.Role = cdoRequiredParticipant
© 2000-2001 Microsoft Corporation. All rights reserved.


Delete Method

Removes the specified Attendee object from the collection.

[Visual Basic,VBScript]
Sub Delete(Index as Long)
[C++]
HRESULT Delete(long* Index);
[IDL]
HRESULT Delete([in] LONG Index);
Index
The ordinal index of the Attendee object to remove from the collection.

Remarks

The collection index always ranges from 1 to the value returned by the Count property.


IAuditTrail Interface

Supports methods for writing entries in an audit trail.

IID
CD001102-8B95-11D1-82DB-00C04FB1625D
Extends
IDispatch

Member Summary

Methods

Name | Description
Bind | Binds audit trail object to a process instance.
AddEntry | Adds entry to audit trail object.

Remarks

The workflow engine uses the object implementing the IAuditTrail interface in case of errors during a state transition. Similarly, the engine uses the implementation when it gets an unhandled exception during an asynchronous event.

This interface needs to be implemented by any audit trail provider used by workflow. The IProcessDefinition interface has an AuditTrailProvider property that contains the ProgID of your audit trail provider. You can use the audit trail provider that comes with CDO for Microsoft Exchange 2000 Server--AuditTrailEventLog. You can also write your own audit trail provider by implementing the IAuditTrail interface.

Exchange 2000 Server setup automatically installs the CDO Workflow Audit Trail component category (CATID). If you want your custom audit trail provider to be visible in the Workflow Designer for Exchange 2000 Server, your audit trail provider must implement this CATID.

Example

The typical workflow developer does not create AuditTrail objects directly. Use the IWorkflowSession AddAuditEntry method to write to the audit trail.

See Also

AuditTrailEventLog

IProcessDefinition

© 2000-2001 Microsoft Corporation. All rights reserved.


Bind Method

Bind audit trail to a process instance.

[Visual Basic,VBScript]
Sub Bind(pProcessInstance As ProcessInstance)
[C++]
HRESULT Bind(IProcessInstance* pProcessInstance);
[IDL]
HRESULT Bind([in] IProcessInstance* pProcessInstance);

Remarks

You use this method only if you are not using the CDO Workflow Event Sink but are calling the workflow engine. Otherwise, the workflow engine takes care of binding the AuditTrailProvider to the ProcessInstance.

An instance of the AuditTrailProvider class is created automatically by the workflow engine in the following cases:

  • When a new ProcessDefinitionURL is set on a process instance (IProcessInstance::put_ProcessDefinitionURL() is called).
  • When a process instance is loaded (IProcessInstance::DataSource::Open() is called).

The IAuditTrail::Bind() method is called immediately after creation of the AuditTrailProvider object.

The workflow engine calls IAuditTrail::Bind(0) in the end of Advance() and OnAbort() to release the IProcessInstance pointer. If you are implementing an AuditTrailProvider, make sure it supports this behavior.

If you are implementing an event sink or calling the workflow engine from an ASP page, always call IAuditTrail::Bind(0) when the audit trail is not needed any more or goes out of scope. Otherwise neither the ProcessInstance object nor the AuditTrailProvider object will be destroyed.

Example

The following function uses the Bind method of IAuditTrail as implemented by the AuditTrailEventLog object. The function is given a reference to a ProcessInstance object. It creates an AuditTrail object by using the ProgID of AuditTrailEventLog. Then it binds the audit trail provider to the ProcessInstance.

[Visual Basic]
Function bATBind(iPI As CDOWF.ProcessInstance) As Boolean
   On Error Resume Next
   bATBind = True
   Dim iAT As Object

   Set iAT = CreateObject("CDOWF.AuditTrailEventLog")
   iAT.Bind iPI

   If Err.Number <> S_OK Then
      ' Error handling code
      '...
      bATBind = False
   Else
      iAT.AddEntry "Bind Succeeded."
   End If

   iAT.Bind Nothing

End Function

See Also

IAuditTrail Interface

AuditTrailEventLog

IProcessDefinition

© 2000-2001 Microsoft Corporation. All rights reserved.


AddEntry Method

Add entry to audit trail.

[Visual Basic,VBScript]
Sub AddEntry( bsDescription As String,
              [hResult As Long],
              [eEvent As CdoWfAuditTrailEvents = cdowfATECustom],
              [varStateChangeInfo] ,
              [varUserSid] )
[C++]
HRESULT AddEntry(BSTR bsDescription,
                     long hResult,
                     CdoWfAuditTrailEvents eEvent,
                     VARIANT varStateChangeInfo) ,
                     VARIANT varUserSid);

[IDL]
HRESULT AddEntry( [in]BSTR bsDescription,
                    [in, defaultvalue(0)]long hResult,
                    [in, defaultvalue(cdowfATECustom)]CdoWfAuditTrailEvents eEvent,
                    [in, optional]VARIANT varStateChangeInfo),
                    [in, optional] VARIANT varUserSid);

Remarks

bsDescription
A string containing a textual description of the audit trail entry. This can be an empty string.
long hResult
The result of operation being logged. Negative hResult indicates an error.
CdoWfAuditTrailEvents eEvent
Specifies the type of audit trail entry.
varStateChangeInfo
Can be either empty or an array of strings that describe the state change information. In C++ it can be either an empty VARIANT or a VARIANT containing a SAFEARRAY of 5 BSTR. In Microsoft® Visual Basic® it can either be omitted or contain an array of 5 Strings. The five strings represent, in order: New State, Old State, Caption, Event Type, ID.
varUserSid
(optional) Contains a security identifier (SID). The VARIANT type is either VT_EMPTY or VT_ARRAY | VT_UI1. The value is a SAFEARRAY of bytes corresponding to the SID.

You use AddEntry() to log event information to the configured AuditTrailProvider, which can be the AuditTrailEventLog provider supplied with Workflow for Microsoft® Exchange 2000 Server, or one you wrote yourself.

The workflow engine calls AddEntry() for every state transition. The information written to the AuditTrailProvider specifies whether a state transition was successful. Success entries are added only if they are enabled. You can enable success entries by:

  • Setting http://schemas.microsoft.com/cdo/workflow/enablesuccessentries = True in the event sink registration item.
  • Selecting a check box in Microsoft Workflow Designer for Exchange 2000 Server.

AddEntry() can also be called from script using WorkflowSession.AddAuditEntry. The workflow engine assigns cdowfATECustom to eEvent for entries made by script.

Example

The following example illustrates the use of the IWorkflowSession AddAuditEntry method, which uses the IAuditTrail AddEntry method. The example code writes to the audit trail affirmative messages that help the developer to trace the progress of the code. This is useful in debugging a workflow application.

Using the AddAuditEntry method is the preferred way to log messages for most typical application developers. Normally, you won't use the AddEntry method directly, unless you are implementing your own audit trail provider.

[Visual Basic]
Sub AddProp()

WorkflowSession.TrackingTable.MoveFirst

For i = 0 To WorkflowSession.TrackingTable.RecordCount - 1 Step 1

   If WorkflowSession.Sender = WorkflowSession.TrackingTable.fields("email").Value Then
      WorkflowSession.AddAuditEntry "email address matched"

      If "A" = WorkflowSession.TrackingTable.fields("state").Value Then
         'the state value here is hard coded you will have to
         'change this for your own action table
         WorkflowSession.AddAuditEntry "state matched"

         WorkflowSession.TrackingTable.fields.Item("custom0").Value = WorkflowSession.ReceivedMessage.fields("Amount").Value

         WorkflowSession.AddAuditEntry "added the value to the customfield"
         WorkflowSession.TrackingTable.Update
      End If
   End If
   WorkflowSession.TrackingTable.MoveNext
Next
WorkflowSession.DeleteReceivedMessage

End Sub

See Also

IAuditTrail Interface

AuditTrailEventLog

IProcessDefinition

© 2000-2001 Microsoft Corporation. All rights reserved.


IBodyPart Interface

The IBodyPart interface defines a set of methods and properties that you can use to manipulate message body parts.

IID
CD000021-8B95-11D1-82DB-00C04FB1625D
Extends
IDispatch

Member Summary

Properties

Name | Type | Description
BodyParts (Read-Only) | [Visual Basic] IBodyParts [C++] IBodyParts* | The BodyParts collection for this object.
Charset | [Visual Basic] String [C++] BSTR | The character set for the text-type body parts.
ContentClass | [Visual Basic] String [C++] BSTR | The content class for the body part.
ContentClassName | [Visual Basic] String [C++] BSTR | Deprecated. Not used.
ContentMediaType | [Visual Basic] String [C++] BSTR | The content type and subtype of the body part.
ContentTransferEncoding | [Visual Basic] String [C++] BSTR | The encoding mechanism used when encoding the body part content.
DataSource (Read-Only) | [Visual Basic] IDataSource [C++] IDataSource* | The IDataSource interface on the object.
Fields (Read-Only) | [Visual Basic] ADODB.Fields [C++] Fields* | The Fields collection for the object.
FileName (Read-Only) | [Visual Basic] String [C++] BSTR | The filename parameter attribute commonly used with the Content-Disposition header field.
Parent (Read-Only) | [Visual Basic] IBodyPart [C++] IBodyPart* | The parent body part object for the object.

Methods

Name | Description
AddBodyPart | Adds a BodyPart object to the BodyParts collection and returns a reference to the newly added object.
GetDecodedContentStream | Returns an ADO Stream object (exposing the _Stream interface) containing the body part content in decoded format.
GetEncodedContentStream | Returns an ADO Stream object (exposing the _Stream interface) containing the body part content in encoded format.
GetFieldParameter | Returns the specified parameter value for the specified MIME header field.
GetInterface | Returns the specified dual interface on the object.
GetStream | Returns an ADO Stream object (exposing the _Stream interface) containing the body part content.
SaveToFile | Saves the decoded body part content to a disk file.

Remarks

A message body that contains more than plain US-ASCII text is subdivided into parts. Examples of body parts include text, attachments, inline HTML pages, alternative representations of HTML pages, and so on. The IBodyPart interface defines a set of abstract methods and properties that you can use to manipulate message body parts.

Body parts are arranged hierarchically in a MIME-formatted message. For example, a message that contains only attachments has a two-level hierarchy — the first level includes the message content and the second level contains each attachment. The IBodyPart interface supports such hierarchies by exposing the BodyParts property. Navigating down one level from an implementing object returns a collection of objects, each of which exposes IBodyPart.

Each object that exposes the IBodyPart interface provides access to content in serialized format using the GetDecodedContentStream or GetEncodedContentStream methods. Both methods return an ADO Stream object (exposing an _Stream interface) containing the content in decoded or encoded format, respectively. Content encoding depends upon whether the message body is formatted using MIME or UUENCODE. This behavior is controlled at the Message object level using the IMessage.MIMEFormatted property.

You can also use the GetStream method to return the entire body part and all subparts in serialized, encoded format. For MIME-formatted messages, this stream contains the mail headers (such as Content-Type) and the content encoded using the mechanism specified by Content-Transfer-Encoding.

For MIME-formatted messages, you must set the Content-Type and Content-Disposition header fields for each body part. Properties on the IBodyPart interface enable you to update these headers quickly. Such properties include the ContentMediaType property, which can be used to set the media-type portion of the Content-Type header. If the object contains a text MIME entity, you can use the Charset property to update the "charset" parameter used with the Content-Type header. Similarly, the ContentTransferEncoding property can be used to update the Content-Transfer-Encoding header for the part. However, all of the header fields are contained in the IBodyPart.Fields collection. You can update any field or add new fields using this collection. The Fields collection returned by the IBodyPart.Fields property is a copy of the fields. To commit changes to the fields, you must call Fields.Update.

Example

The following example demonstrates manually constructing the MIME structure for a message that contains two alternative representations of a message along with an attachment. This example is for illustrative purposes only. The same message structure could be created using just the IMessage.HTMLBody property and IMessage.AddAttachment method. The example has four steps, as follows:

  1. Create a Message object.
  2. Add two BodyPart objects to the Message object's BodyParts collection. The first will have content-type set to multipart/alternative and will contain the two representations of the message. The second will contain the attachment.
  3. Add two BodyPart objects to the multipart/alternative BodyPart. Each will contain a given representation of the message, in this case "text/plain" and "text/html."
  4. Create a third BodyPart object at the first level and add an image (.gif) file to it. This body part will contain the attachment for the message.

These steps result in the following hierarchy of MIME entities:

Message (multipart/mixed)
    BodyPart 1 (multipart/alternative)
        BodyPart 1.1 (text/plain)
        BodyPart 1.2 (text/html)
    BodyPart 2 (image/gif)
               (Content-Disposition: attachment)
[Visual Basic]
Dim iMsg As New CDO.Message
Dim iBp As CDO.IBodyPart
Dim iBp2 As CDO.IBodyPart
Dim iBp3 As CDO.IBodyPart
Dim Stm As ADODB.Stream

With iMsg
   .From = "Sender@microsoft.com"
   .To = "PersonA@microsoft.com, PersonB@microsoft.com"
   .Subject = "A html and text message with attachment."
End With

''''''''''''''''''''''''''''''''
' Level 1: multipart/mixed (root)
''''''''''''''''''''''''''''''''
Set iBp = iMsg         ' returns IBodyPart on object
iBp.ContentMediaType = "multipart/mixed"

''''''''''''''''''''''''''''''''
' Level 2: multipart/alternative
''''''''''''''''''''''''''''''''
Set iBp2 = iBp.AddBodyPart
iBp2.ContentMediaType = "multipart/alternative"

''''''''''''''''''''''''''
' Level 3: text/plain
''''''''''''''''''''''''''
Set iBp3 = iBp2.AddBodyPart
With iBp3
   .ContentMediaType = "text/plain"
   .ContentTransferEncoding = "7bit"
   Set Stm = .GetDecodedContentStream
   Stm.WriteText "Here is the plain text version of the message"
   Stm.Flush
End With

''''''''''''''''''''''''''
' Level 3: text/html
''''''''''''''''''''''''''
Set iBp3 = iBp2.AddBodyPart
With iBp3
   .ContentMediaType = "text/html"
   .ContentTransferEncoding = "quoted-printable"
   Set Stm = .GetDecodedContentStream
   Stm.WriteText "<html><body><p>Here is the HTML version of the message</p></body></html>"
   Stm.Flush
End With

'''''''''''''''''''''''''''''
' Level 2: image/gif
'''''''''''''''''''''''''''''
Dim Flds As ADODB.Fields
Set iBp2 = iBp.AddBodyPart
With iBp2
   .ContentMediaType = "image/gif"
   .ContentTransferEncoding = "base64"
   Set Flds = iBp2.Fields
   Flds("urn:schemas:mailheader:content-disposition") = _
             "attachment; filename=""myimage.gif"""
   Flds.Update
   Set Stm = .GetDecodedContentStream
   Stm.LoadFromFile "c:\somewhere\myimage.gif"
   Stm.Flush
End With

Debug.Print iMsg.GetStream.ReadText
[C++,IDL]
/*
**   Must have
**   %SYSTEMDRIVE%\program files\common files\microsoft shared/cdo
**   %SYSTEMDRIVE%\program files\common files\system\ado\
**   in your include path.
*/
#ifndef _CORE_EXAMPLE_HEADERS_INCLUDED
#define _CORE_EXAMPLE_HEADERS_INCLUDED
#import <msado15.dll> no_namespace
#import <cdoex.dll> no_namespace
#include <iostream.h>
#endif

bool IBodyPart_Main_Example() {

    IMessagePtr iMsg(__uuidof(Message));
    IBodyPartPtr iBp;
    IBodyPartPtr iBp2;
    IBodyPartPtr iBp3;
    _StreamPtr   Stm;

    iMsg->From    = "Sender@microsoft.com";
    iMsg->To      = "PersonA@microsoft.com, PersonB@microsoft.com";
    iMsg->Subject = "A html and text message with attachment.";

    /*''''''''''''''''''''''''''''''''
    ' Level 1: multipart/mixed (root)
    ''''''''''''''''''''''''''''''''*/
    iBp = iMsg;
    iBp->ContentMediaType = "multipart/mixed";

    /*''''''''''''''''''''''''''''''
    ' Level 2: multipart/alternative
    ''''''''''''''''''''''''''''''''*/
    iBp2 = iBp->AddBodyPart(-1);
    iBp2->ContentMediaType = "multipart/alternative";

    /*'''''''''''''''''''''''''
    ' Level 3: text/plain
    ''''''''''''''''''''''''''*/
    iBp3 = iBp2->AddBodyPart(-1);
    iBp3->ContentMediaType        = "text/plain";
    iBp3->ContentTransferEncoding = "7bit";
    Stm = iBp3->GetDecodedContentStream();
    Stm->WriteText(
                   "Here is the plain text version of the message",
                   adWriteChar
                  );
    Stm->Flush();

    /*'''''''''''''''''''''''''
    ' Level 3: text/html
    '''''''''''''''''''''''''*/
    iBp3 = iBp2->AddBodyPart(-1);
    iBp3->ContentMediaType        = "text/html";
    iBp3->ContentTransferEncoding = "quoted-printable";
    Stm = iBp3->GetDecodedContentStream();
    Stm->WriteText(
                   "<html><body><p>Here is the HTML version of the message</p></body></html>",
                   adWriteChar
                  );
    Stm->Flush();

    /*''''''''''''''''''''''''''''
    ' Level 2: image/gif
    '''''''''''''''''''''''''''''*/
    iBp2 = iBp->AddBodyPart(-1);
    iBp2->ContentMediaType = "image/gif";
    iBp2->ContentTransferEncoding = "base64";
    Stm = iBp2->GetDecodedContentStream();
    Stm->LoadFromFile("myimage.gif");
    Stm->Flush();

    // print message stream to console
    cout << iMsg->GetStream()->ReadText(-1) << endl;

   return true;
}
[VBScript]
Dim iMsg
Dim iBp1
Dim iBp2
Dim iBp3
Dim Stm

Set iMsg = CreateObject("CDO.Message")

With iMsg
   .From    = "Sender@microsoft.com"
   .To      = "PersonA@microsoft.com, PersonB@microsoft.com"
   .Subject = "A html and text message with attachment."
End With

''''''''''''''''''''''''''''''''
' Level 1: multipart/mixed (root)
''''''''''''''''''''''''''''''''
Set iBp = iMsg.BodyPart
iBp.ContentMediaType = "multipart/mixed"

''''''''''''''''''''''''''''''''
' Level 2: multipart/alternative
''''''''''''''''''''''''''''''''
Set iBp2 = iBp.AddBodyPart
iBp2.ContentMediaType = "multipart/alternative"

''''''''''''''''''''''''''
' Level 3: text/plain
''''''''''''''''''''''''''
Set iBp3 = iBp2.AddBodyPart
With iBp3
   .ContentMediaType        = "text/plain"
   .ContentTransferEncoding = "7bit"
   Set Stm = .GetDecodedContentStream
   Stm.WriteText "Here is the plain text version of the message"
   Stm.Flush
End With

''''''''''''''''''''''''''
' Level 3: text/html
''''''''''''''''''''''''''
Set iBp3 = iBp2.AddBodyPart
With iBp3
   .ContentMediaType        = "text/html"
   .ContentTransferEncoding = "quoted-printable"
   Set Stm = .GetDecodedContentStream
   Stm.WriteText "<html><body><p>Here is the HTML version of the message</p></body></html>"
   Stm.Flush
End With

'''''''''''''''''''''''''''''
' Level 2: image/gif
'''''''''''''''''''''''''''''
Dim Flds
Set iBp2 = iBp.AddBodyPart
With iBp2
   .ContentMediaType = "image/gif"
   .ContentTransferEncoding = "base64"
   Set Flds = iBp2.Fields
   Flds("urn:schemas:mailheader:content-disposition") = "attachment; filename=""myimage.gif"""
   Flds.Update
   Set Stm = .GetDecodedContentStream
   Stm.LoadFromFile "c:\somewhere\myimage.gif"
   Stm.Flush
End With

Wscript.Echo iMsg.GetStream.ReadText
© 2000-2001 Microsoft Corporation. All rights reserved.


BodyParts Property

The object's BodyParts collection.

[Visual Basic]
Property BodyParts as IBodyParts
read-only
[C++]
HRESULT get_BodyParts(IBodyParts** pVal);
[IDL]
HRESULT [propget] BodyParts([out,retval] IBodyParts** pVal);

Remarks

A MIME body part content type can be either single or multipart. A single body part represents a single entity, such as text or an image. A multipart body part consists of child body parts. You can access a multipart body part's children using the object's BodyParts property.


Charset Property

The character set for the body part.

[Visual Basic]
Property Charset as String
[C++]
HRESULT get_Charset(BSTR* pVal);
HRESULT put_Charset(BSTR Val);
[IDL]
HRESULT [propget] Charset([out,retval] BSTR* pVal);
HRESULT [propput] Charset([in] BSTR Val);

Remarks

The Charset property corresponds to the "charset" attribute parameter of the Content-Type header field of RFC 2045. Charset does not include any types or subtypes. Only text body parts have an associated character set.

The default content type under RFC 822 is plain text US-ASCII (ANSI X3.4-1986). The currently permissible character set names include "us-ascii", "iso-8859-nnnnn", and "x-ttttt", where "nnnnn" is one to five decimal digits representing an ISO code page and "ttttt" is an extension token. Character set "iso-8859-1" is the same as "us-ascii". However, certain message transfer agents and user agents might require one of these two strings and not accept the other.

Note When working with body parts that contain mixed character sets, you can specify the character set used in the message's header fields by setting the Message object's IBodyPart.Charset property. There is no corresponding top-level charset parameter in the transmitted stream; this value is used to encode these headers when they are set using the IMessage interface properties, or through fields within the urn:schemas:httpmail: namespace using the mechanism defined in RFC 1522.

You can use any Charset value that is installed/supported on your system. The following table defines some of the module constants that are available through the type library and header files for use with the Charset property.

cdoCharset Module Constants

Constant | Value
cdoBIG5 | "big5"
cdoEUC_JP | "euc-jp"
cdoEUC_KR | "euc-kr"
cdoGB2312 | "gb2312"
cdoISO_2022_JP | "iso-2022-jp"
cdoISO_2022_KR | "iso-2022-kr"
cdoISO_8859_1 | "iso-8859-1"
cdoISO_8859_2 | "iso-8859-2"
cdoISO_8859_3 | "iso-8859-3"
cdoISO_8859_4 | "iso-8859-4"
cdoISO_8859_5 | "iso-8859-5"
cdoISO_8859_6 | "iso-8859-6"
cdoISO_8859_7 | "iso-8859-7"
cdoISO_8859_8 | "iso-8859-8"
cdoISO_8859_9 | "iso-8859-9"
cdoKOI8_R | "kio8-r"
cdoShift_JIS | "shift-jis"
cdoUS_ASCII | "us-ascii"
cdoUTF_7 | "utf-7"
cdoUTF_8 | "utf-8"

The contents of Charset are case-insensitive. The default value is "us-ascii".


ContentClass Property

Sets and retrieves a body part's content class value.

[Visual Basic]
Property ContentClass as String
[C++]
HRESULT get_ContentClass(BSTR* pVal);
HRESULT put_ContentClass(BSTR Val);
[IDL]
HRESULT [propget] ContentClass([out,retval] BSTR* pVal);
HRESULT [propput] ContentClass([in] BSTR Val);

Remarks

This property corresponds to the urn:schemas:mailheader:content-class field in the object's Fields collection.

CDO for Microsoft® Windows® 2000 COM classes that provide IBodyPart implementations automatically generate the urn:content-classes:message value. This class header is present only in the message headers or in MIME entity headers for an embedded message (that has the Content-Type "message/rfc822.")

Example

Dim iBp as CDO.BodyPart
... ' get a bodypart containing an embedded message
    ' set it to oBp
iBp.ContentClass = "urn:content-classes:message"


ContentClassName Property

Deprecated. Do not use.

[Visual Basic]
Property ContentClassName as String
[C++]
HRESULT get_ContentClassName(BSTR* pVal);
HRESULT put_ContentClassName(BSTR Val);
[IDL]
HRESULT [propget] ContentClassName([out,retval] BSTR* pVal);
HRESULT [propput] ContentClassName([in] BSTR Val);


ContentMediaType Property

Contains type and subtype identifiers that specify the nature of the data in a body part.

[Visual Basic]
Property ContentMediaType as String
[C++]
HRESULT get_ContentMediaType(BSTR* pVal);
HRESULT put_ContentMediaType(BSTR Val);
[IDL]
HRESULT [propget] ContentMediaType([out,retval] BSTR* pVal);
HRESULT [propput] ContentMediaType([in] BSTR Val);

Remarks

The ContentMediaType property corresponds to the type and subtype of the Content-Type header field of RFC 2045.

This property corresponds to the urn:schemas:mailheader:content-type header field available in the Fields collection.

The format for the contents of ContentMediaType is "<type>/<subtype>". Common types and subtypes include:

  • image/gif, image/jpeg
  • message/external-body, message/partial, message/rfc822
  • multipart/alternative, multipart/digest, multipart/mixed, multipart/related
  • text/html, text/plain

The following CdoContentTypeValues string constants are provided for use with the ContentMediaType property:

CdoContentTypeValues Module Constants

Constant | Value | Description
cdoGif | "image/gif" | Image encoded using Graphics Interchange Format (GIF)
cdoJpeg | "image/jpeg" | Image encoded using Joint Photographic Experts Group format (ISO/IEC 10918)
cdoMessageExternalBody | "message/external-body" | Pointer to message content outside this message
cdoMessagePartial | "message/partial" | One piece of a fragmented message
cdoMessageRFC822 | "message/rfc822" | Simple e-mail message, not even a forward
cdoMultipartAlternative | "multipart/alternative" | Different versions of same content, simplest first
cdoMultipartDigest | "multipart/digest" | Different messages, including forwarded messages
cdoMultipartMixed | "multipart/mixed" | Body parts to be processed sequentially
cdoMultipartRelated | "multipart/related" | Body parts accessed through URLs
cdoTextHtml | "text/html" | Text with HTML tags
cdoTextPlain | "text/plain" | Unstructured text

The contents of ContentMediaType are case-insensitive. The default value is "text/plain".

Example

Dim iBp as CDO.BodyPart
    ' set a bodypart to oBp
iBp.ContentMediaType = "application/msword"


ContentTransferEncoding Property

Defines the encoding mechanism used when sending an implementing object's contents over the network.

[Visual Basic]
Property ContentTransferEncoding as String
[C++]
HRESULT get_ContentTransferEncoding(BSTR* pVal);
HRESULT put_ContentTransferEncoding(BSTR Val);
[IDL]
HRESULT [propget] ContentTransferEncoding([out,retval] BSTR* pVal);
HRESULT [propput] ContentTransferEncoding([in] BSTR Val);

Remarks

The ContentTransferEncoding property corresponds to the Content-Transfer-Encoding MIME header field of RFC 2045.

This property corresponds to the urn:schemas:mailheader:content-transfer-encoding field for the object. You can therefore set this field using the ContentTransferEncoding property on the interface or by updating the value using the Fields collection.

CDO defines the following string constants and mechanisms for use with the ContentTransferEncoding property:

CdoEncodingType Module Constants

Constant | Value | Meaning
cdo7bit | "7bit" | Simple 7-bit ASCII
cdo8bit | "8bit" | 8-bit coding with line termination characters
cdoBase64 | "base64" | 3 octets encoded into 4 sextets with offset
cdoBinary | "binary" | Arbitrary binary stream
cdoMacBinHex40 | "mac-binhex40" | Macintosh binary to hex encoding
cdoQuotedPrintable | "quoted-printable" | Mostly 7-bit, with 8-bit characters encoded as "=HH"
cdoUuencode | "uuencode" | UUENCODE encoding.

In compliance with RFC 2045, the ContentTransferEncoding property is enforced to be "7bit", "8bit", or "binary" when ContentMediaType indicates a composite content type such as "message" or "multipart". An attempt to encode a composite type with any other mechanism results in an error.

CDO can decode a body part from "mac-binhex40" but cannot encode using this mechanism.

The contents of ContentTransferEncoding are case-insensitive. The default value is "7bit".

Example

Dim iBp as CDO.BodyPart
iBp.ContentTransferEncoding = "base64"


DataSource Property

Returns the IDataSource interface on the object.

[Visual Basic,VBScript]
Property DataSource as IDataSource
read-only
[C++]
HRESULT get_DataSource(IDataSource** pVal);
[IDL]
HRESULT [propget] DataSource([out,retval] IDataSource** pVal);

Remarks

This property returns the IDataSource interface on the object. If the object does not implement the IDataSource interface, the COM exception E_NOTIMPL is raised.

This property is intended to provide a mechanism for interface navigation with scripting languages that do not natively support interface navigation. For programming languages such as C++, Microsoft® Visual Basic®, and Microsoft® Visual J++®, the preferred way to navigate to the IDataSource interface on an object is to use native mechanisms, namely QueryInterface, the Set keyword, or type casting respectively. However, the DataSource property is valid to use from these languages as well.

Example

[Visual Basic]
Dim iMsg as New CDO.Message
Dim iDSrc as CDO.IDataSource
Set iDSrc = iMsg ' the native way
Set iDSrc = Nothing
Set iDSrc = Bp.DataSource  ' this works as well
[VBScript]
Dim iMsg
Dim iBp
Set iMsg = CreateObject("CDO.Message")
Dim iDSrc
' navigate to DataSource in VBScript
Set iDSrc = iBp.DataSource
© 2000-2001 Microsoft Corporation. All rights reserved.


Fields Property

The Fields collection for the object.

[Visual Basic]
Property Fields as ADODB.Fields
read-only
[C++]
HRESULT get_Fields(Fields** pVal);
[IDL]
HRESULT [propget] Fields([out,retval] Fields** pVal);

Remarks

The ADO Fields object is a collection of ADO Field objects that pertain to this object. Each Field object holds a name/value pair defining some header field for the body part. The name is always a string, and the value is a VARIANT. The subtype of the VARIANT depends on the field definition. See the appropriate section of the reference for a list of valid fields to use along with a list of the VARIANT subtypes for each field.

The fields that resize in this collection depend upon the specific implementation. Consult the appropriate COM class for details about available fields.

Note When you use the ADO Fields.Update method, field values are updated only in memory. You must call IDataSource.Save to save the changes to the Web Storage System. To get the IDataSource interface, use the GetInterface method on the CDO object. This code is shown in the following example.

Example

[Visual Basic]
Dim iMsg As New CDO.Message
Dim iBp As CDO.BodyPart
Set iBp = Msg

Dim Flds As ADODB.Fields
Set Flds = iBp.Fields

With Flds
   .Item("urn:schemas:mailheader:content-type") = "application/msword"
   .Item("urn:schemas:mailheader:content-disposition") = "attachment"
   .Update
End With

'Save the fields to the Web Storage System
Dim iDsrc As CDO.IDataSource
Set iDsrc = iBp.GetInterface("IDataSource")
iDsrc.Save

See Also

CDO BodyPart Fields and Streams

© 2000-2001 Microsoft Corporation. All rights reserved.


FileName Property

The FileName property corresponds to the filename parameter attribute used with the Content-Disposition MIME header field.

[Visual Basic]
Property FileName as String
read-only
[C++]
HRESULT get_FileName(BSTR* pVal);
[IDL]
HRESULT [propget] FileName([out,retval] BSTR* pVal);

Remarks

The FileName property corresponds to the filename attribute parameter of the Content-Disposition header field of RFC 2183.

Some applications may interpret the Content-Disposition header field specified as a file to mean that a body part is an attachment. However there is no specifically defined presentation behavior determined by the FileName property.

The default value of FileName is an empty string. If CDO does not recognize the disposition of a body part on an incoming message, it is treated as an attachment.

Example

All message attachments are contained in objects that implement the IBodyPart interface. In the following example, the attachments are enumerated, and all associated file names gathered. We could use these names to render attachment bitmaps in a Upgrade Advantage, save it into a file with this name, or make a guess as to its type if, for example, the attachment simply had Content-Type equal to "application/octet-stream."

[Visual Basic]
Sub ProcessAttachments(iMsg As CDO.Message)
  Dim iBp As CDO.BodyPart
  Dim Filename As String
  Dim Atchmts As CDO.IBodyParts
  Set Atchmts = iMsg.Attachments
  '  Note here that all attachments are contained in body
  '  parts --  the collection
  '  object exposes the IBodyParts interface
  If Atchmts.Count > 0 Then
    For Each iBp In iMsg.Attachments
      Filename = iBp.Filename
      If Not Filename = "" Then
        ' use the file name
      End If
    Next iBp
  End If
End Sub
© 2000-2001 Microsoft Corporation. All rights reserved.


Parent Property

Returns the parent body part object.

[Visual Basic]
Property Parent as IBodyPart
[C++]
HRESULT get_Parent(IBodyPart** pVal);
[IDL]
HRESULT [propget] Parent( [out,retval] IBodyPart** pVal);

Remarks

Message content that is more than plain US-ASCII is arranged in a parent-child hierarchy. You can use the Parent property to navigate up from the current object to the object one level higher. If the object has no parent, as in the case with the Message object, an exception is raised.

As noted above, the Parent object may or may not be an instance of the BodyPart COM class.

Example

[Visual Basic]
Dim iMsg As New CDO.Message
Dim iBp1 As CDO.IBodyPart
Dim iBp2 As CDO.IBodyPart

Set iBp1 = iMsg.AddAttachment("c:\files\file.doc")
Set iBp2 = iBp1.Parent
' we now have the IBodyPart interface on the Message object, as it
' is the parent of the attachment BodyPart object.


AddBodyPart Method

Adds a BodyPart object to the BodyParts collection.

[Visual Basic]
Function AddBodyPart([ByVal Index as Long = -1]) as IBodyPart
[C++]
HRESULT AddBodyPart( long Index = -1, IBodyPart** pVal);
[IDL]
HRESULT AddBodyPart(
  [in, defaultvalue(-1), optional] long Index,
  [out,retval] IBodyPart** pVal
);
Index
The ordinal index within the body parts collection at which the new body part object is to be added. The first element in the collection has an index of 1, and the current last element has an index equal to the value of the collection's Count property. Setting the Index to 1 causes the new body part to be inserted at the beginning of the collection. Setting the Index to -1 causes the new body part to be added (appended) to the end of the collection. Index settings of 0 or less than -1 are invalid.

Remarks

The AddBodyPart method creates a new BodyPart object in the BodyParts collection and then returns the IBodyPart interface on the new object. This method is essentially the same as using the IBodyParts.Add method on this object's BodyParts collection.

If an object already exists in the collection at the point you specify with the Index parameter, the new object is added in its place, and the index values of the existing object, and all following objects, are increased by one.

The MIME specification requires that a multipart item must hold all its content in subparts and not at its own level. Therefore, if AddBodyPart is called on a message that is not multipart and that holds content in its IMessage.HTMLBody or IMessage.TextBody properties, this content is converted to one or more subparts, which become the first elements of the new body parts collection created by AddBodyPart. The new object returned by AddBodyPart is added as the last element in this new collection.

When calling AddBodyPart, the ContentMediaType property is checked for the value "multipart". If not found, ContentMediaType is changed to "multipart/mixed" and a new BodyParts collection is created on the body part to which this body part is being added. If ContentMediaType was already "multipart/alternative", it is changed to "multipart/mixed", and the entire multipart/alternative structure is made a subpart of the body part to which you are adding the new body part. This is necessary because the new body part, being empty, cannot possibly be an alternative rendition of the other subparts of the multipart/alternative structure.

The ContentMediaType of the new body part is set to "application/octet-stream". This prevents the IMessage.HTMLBodyPart or IMessage.TextBodyPart property from mistaking the new body part for HTML or plain text in case it is not one of these types. You should set ContentMediaType to the appropriate value when you obtain the body part from the AddBodyPart method.

Body parts that will contain attachments can also be added directly via the IMessage.AddAttachment method. For simplicity it is recommended that you use the AddAttachment method to associate an attachment with the message.

Example

[Visual Basic]
Dim Flds As ADODB.Fields
Dim Strm As ADODB.Stream

Dim iMsg As New CDO.Message
Dim iBp As CDO.BodyPart

Set iBp = Msg.BodyPart.AddBodyPart
Set Flds = iBp.Fields
Flds("urn:schemas:mailheader:content-type") = "text/plain"
Flds.Update
Set Strm = iBp.GetDecodedContentStream
Strm.WriteText "This is some text"
Strm.Flush

Set iBp = Msg.BodyPart.AddBodyPart
Set Flds = iBp.Fields
Flds("urn:schemas:mailheader:content-type") = "text/html"
Flds.Update
Set Strm = iBp.GetDecodedContentStream
Strm.WriteText "<html><h1>This is some text</h1></html>"
Strm.Flush

Set Flds = iMsg.Fields
Flds("urn:schemas:mailheader:content-type") = "multipart/alternative"
Flds.Update
© 2000-2001 Microsoft Corporation. All rights reserved.


GetDecodedContentStream Method

Returns an ADO Stream object containing the body part content in decoded format.

[Visual Basic]
Function GetDecodedContentStream( ) as ADODB.Stream
[C++]
HRESULT GetDecodedContentStream( _Stream** pVal);
[IDL]
HRESULT GetDecodedContentStream([out,retval] _Stream** pVal);

Remarks

CDO uses the current value of the ContentTransferEncoding property and the MIMEFormatted property to determine which encoding mechanism to use to decode or encode the contents of the implementing object. It is the programmer's responsibility to have the appropriate value set in ContentTransferEncoding.

The Stream object returned contains a read/write copy of the current (decoded) contents of the object implementing IBodyPart. If you modify the contents within the returned Stream object, you must call the Flush method to commit the changes back into the object.

The GetDecodedContentStream method returns an error if called on an object that has Content-Type set to "multipart."

To obtain the encoded content, use the GetEncodedContentStream method.

Example

[Visual Basic]
Dim iMsg As New CDO.Message
Dim iBp As CDO.IBodyPart
Set iBp = iMsg.BodyPart.AddBodyPart
Dim Strm As ADODB.Stream
Set Strm = iBp.GetDecodedContentStream
Strm.WriteText "This is some text for the body part"
Strm.Flush
' add more body parts, etc
'...
iMsg.Send

See Also

Bodypart Fields and Streams

Saving Messages Into ADO Stream Objects

GetEncodedContentStream Method

© 2000-2001 Microsoft Corporation. All rights reserved.


GetEncodedContentStream Method

Returns an ADO Stream object containing the body part content in encoded format.

[Visual Basic]
Function GetEncodedContentStream() as ADODB.Stream
[C++]
HRESULT GetEncodedContentStream(_Stream** pVal);
[IDL]
HRESULT GetEncodedContentStream([out,retval] _Stream** pVal);

Remarks

CDO uses the current value of the ContentTransferEncoding property to determine which encoding mechanism to use to decode or encode body part contents. CDO uses the encoding specified in ContentTransferEncoding to encode the contents. Although CDO provides standard defaults for ContentTransferEncoding, it is the programmer's responsibility to have the appropriate value set before calling GetEncodedContentStream.

The Stream object returned contains a read/write copy of the current (encoded) contents of the object implementing IBodyPart. If you modify the contents within the returned Stream object, you must call the Flush method to commit the changes back into the object.

The GetEncodedContentStream method returns an error if called on a multipart body part because these body parts have no content, and simply act as structure units in the MIME hierarchy.

To obtain the content in its decoded form, use the GetDecodedContentStream method.

Example

[Visual Basic]
'  This is a manual way to copy an attachment
Dim iMsg As New CDO.Message
Dim iBp As CDO.IBodyPart
Set iBp = iMsg.AddAttachment("c:\report.doc")
Dim Stm As ADODB.Stream
Set Stm = iBp.GetEncodedContentStream

Dim iMsg2 As New CDO.Message
Dim iBp2 As CDO.IBodyPart
Dim Flds As ADODB.Fields

Set iBp2 = iMsg2.BodyPart.AddBodyPart

Set Flds = iBp2.Fields
Flds("urn:schemas:mailheader:content-disposition") = "attachment"
Flds("urn:schemas:mailheader:content-transfer-encoding") = "base64"
Flds.Update

Dim Stm2 As ADODB.Stream
Set Stm2 = iBp2.GetEncodedContentStream
Stm.CopyTo Stm2
Stm2.Flush
 ' go on to send messages

See Also

CDO BodyPart Fields and Streams

Saving Messages Into ADO Stream Objects

GetDecodedContentStream Method

© 2000-2001 Microsoft Corporation. All rights reserved.


GetFieldParameter Method

Returns the value of the specified parameter for the specified MIME header field.

[Visual Basic]
Function GetFieldParameter(FieldName as String, Parameter as String) as String
[C++]
HRESULT GetFieldParameter(BSTR FieldName, BSTR Parameter, BSTR* pVal);
[IDL]
HRESULT GetFieldParameter([in] BSTR FieldName, [in] BSTR Parameter, [out,retval] BSTR* pVal);
FieldName
The fully qualified name of the field, such as urn:schemas:mailheader:content-type. CDO string constants are provided for the various field names, such as cdoContentDisposition.
Parameter
The name of the parameter, such as "filename" or "boundary."

Remarks

The GetFieldParameter method can be used to access parameters for MIME fields that contain nested information. One example is the standard MIME header Content-Disposition (the fully resolved name for CDO is urn:schemas:mailheader:content-disposition). When the content disposition is set to "attachment", the field value normally contains a "filename=[name]" portion to indicate to the receiver suggested names to use when storing the content on the file system. You can use the GetFieldParameter to directly access this value, rather than having to parse the string yourself.

Example

This example demonstrates using GetFieldParameter to extract the charset parameter from a Content-Type: text/plain mail header and the border parameter from a Content-Type: multipart header. The Charset property does the first one for you.

[Visual Basic]
Function GetCharset(ByRef iBp As CDO.IBodyPart) As String
   GetTextBodyCharset = iBp.GetFieldParameter("urn:schemas:mailheader:content-type", "charset")
End Function

Function GetMultipartBoundary(iBp As CDO.IBodyPart) As String
  If InStr(0, iBp.ContentMediaType, "multipart") > 1 Then
    GetMultipartBoundary = iBp.GetFieldParameter("urn:schemas:mailheader:content-type", "boundary")
  Else
    GetMultipartBoundary = ""
  End If
End Function
© 2000-2001 Microsoft Corporation. All rights reserved.


GetInterface Method

Returns the specified dual interface on the object.

[Visual Basic]
Function GetInterface(ByVal Interface as String) as Object
[C++]
HRESULT GetInterface(BSTR Interface, IDispatch** pVal);
[IDL]
HRESULT GetInterface([in] BSTR Interface, [out,retval] IDispatch** pVal);
Interface
The name of the interface. The list of possible interfaces to return depends upon the COM class that provides the implementation.

Remarks

The GetInterface method is primarily intended as a generic interface navigation aid to scripting languages that do not support such navigation directly. Most COM classes that provide implementations of the IMessage interface expose additional dual interfaces that are accessible by scripting languages only through properties on the interface, such as BodyPart and DataSource, or through using the GetInterface method. When properties do not exist on the interface to return these interfaces, the GetInterface method must be used.

The list of valid interface names to pass to GetInterface is dependent upon a specific implementation. As a general rule, the name of the desired interface should match the physical name of the interface as it appears in the type library or .idl file. Check the appropriate COM class for a list of exposed dual interfaces. If the object does not support the requested interface, an exception is raised with the HRESULT value of E_INVALIDARG.

Example

VBScript
' assume iBodyPart contains a valid IBodyPart interface reference
Dim iMessage
Set iMessage = iBodyPart.GetInterface("IMessage")
...
JScript
' assume iBodyPart contains a valid IBodyPart interface reference
var iMsg
iMsg = iBodyPart.GetInterface("IMessage");
...


GetStream Method

Returns an ADO Stream object reference containing the headers and content of this body part.

[Visual Basic]
Function GetStream() as ADODB.Stream
[C++]
HRESULT GetStream(_Stream** pVal);
[IDL]
HRESULT GetStream([out,retval] _Stream** pVal);

Remarks

The GetStream method returns a copy of the entire body part, including its headers, content, and all subparts, in serialized (transport) form within a single Stream object. To obtain a stream containing just the body part contents, use either GetDecodedContentStream or GetEncodedContentStream.

Calling GetStream returns a copy of the contents of this BodyPart object in the returned Stream object. If you modify the content in the returned Stream object and you wish to then update the location from whence you retrieved the stream, you must commit the changes back by calling the Flush (_Stream.Flush) method.

Example

[Visual Basic]
Dim iMsg As New CDO.Message
Dim iBp As CDO.IBodyPart
Set iBp = iMsg.AddAttachment("c:\report.doc")
Dim Stm As ADODB.Stream
Set Stm = iBp.GetStream

' this stream has mail headers and the content
' in encoded format for the report.doc attachment

The AddAttachment method sets up standard header fields automatically. The stream contents could look something like

Content-Type: application/msword;
        name="report.doc"
Content-Transfer-Encoding: base64
Content-Disposition: attachment;
        filename="report.doc"

0M8R4KGxGuEAAAAAA....(etc)
////////////////////////////////

See Also

CDO BodyPart Fields and Streams

© 2000-2001 Microsoft Corporation. All rights reserved.


SaveToFile Method

Saves the decoded contents of a body part to a disk file.

[Visual Basic]
Sub SaveToFile(ByVal FileName as String)
[C++]
HRESULT SaveToFile(BSTR FileName);
[IDL]
HRESULT SaveToFile([in] BSTR FileName);
FileName
The full path and file name to be used for the URL for the disk file.

Remarks

Local Drive and FTP formats are supported. For local drive files you can use the "File://" prefix, thus the URL argument File://C:\mytext.txt and C:\mytext.txt are both legal and function identically.

"HTTP://" locations are not supported.

Example

[Visual Basic]
Dim iMsg As New CDO.Message
Dim iBp As CDO.IBodyPart
Set iBp = iMsg.AddAttachment("c:\report.doc")
iBp.SaveToFile "d:\backup\report.doc"


IBodyParts Interface

The IBodyParts interface defines properties and methods used to access a collection of BodyPart objects.

IID
CD000023-8B95-11D1-82DB-00C04FB1625D
Extends
IDispatch

Member Summary

Properties

Name | Type | Description
Count (Read-only) | [Visual Basic]Long [C++] Long | Returns the number of BodyPart objects in the collection.
Item (Read-only) | [Visual Basic] IBodyPart [C++] IBodyPart* | Returns a reference to the object at a given index in the collection.
_NewEnum (Read-only) | [C++] IUnknown* [Visual Basic] (Used in For Each In) | Returns an IEnumVARIANT interface on an enumeration object. (This property is hidden from Microsoft® Visual Basic® and is used in For Each In constructs)

Methods

Name | Description
Add | Adds a BodyPart object to the collection, then returns a reference to the newly added object.
Delete | Removes the specified BodyPart object from the collection.
DeleteAll | Removes all BodyPart objects from the collection.

Remarks

COM classes that provide an implementation of the IBodyParts interface present ordered collections of BodyPart objects. The indexing of the collection always ranges from 1 to the value returned by the Count property.


Count Property

Returns the number of BodyPart objects in the collection.

[Visual Basic]
Property Count as Long
read-only
[C++]
HRESULT get_Count(long* pVal);
[IDL]
HRESULT [propget] Count([out,retval] long* pVal);

Example

Sub ProcessBodyParts( iBp as CDO.IBodyPart )
  Dim Count as Long

  ' Process body part code here

  ' Recursively descend body part hierarchy
  Dim iBp_local as CDO.IBodyPart
  Count = iBp.Count
  If Count > 1 Then
    Dim iBps as CDO.IBodyParts
    Set iBps = iBp.BodyParts
    For I = 1 to Count
      Set iBp_local = iBps(I)
      ProcessBodyPart iBp_local
    Next I
  End If
End Sub
© 2000-2001 Microsoft Corporation. All rights reserved.


Item Property

Returns the BodyPart object specified by the index.

[Visual Basic]
Property Item(ByVal Index as Long) as IBodyPart
read-only
default
[C++]
HRESULT get_Item( long Index, IBodyPart** pVal);
[IDL]
HRESULT [propget,id(0)] Item([in] long Index, [out,retval] IBodyPart** pVal);

Remarks

Item is the default member on the interface.

Example

Sub ProcessBodyParts( iBp as CDO.IBodyPart )
  Dim Count as Long

  ' Process body part code here

  ' Recursively descend body part hierarchy
  Dim iBp_local as CDO.IBodyPart
  Count = iBp.Count
  If Count > 1 Then
    Dim iBps as CDO.IBodyParts
    Set iBps = iBp.BodyParts
    For I = 1 to Count
                                ' Item is default
                                ' Explicitly typing ".Item" is unnecessary
      Set iBp_local = iBps.Item(I)
      ProcessBodyPart iBp_local
    Next I
  End If
End Sub
© 2000-2001 Microsoft Corporation. All rights reserved.


_NewEnum Property

Returns an IEnumVARIANT interface on an enumeration object for the collection. This property is hidden from Microsoft® Visual Basic® and Microsoft® Visual Basic® Scripting Edition (VBScript).

[Visual Basic]
Used automatically in For Each In constructs
[C++]
HRESULT get__NewEnum(IUnknown** pVal);
[IDL]
HRESULT [propget] _NewEnum([out,retval] IUnknown** pVal);

Remarks

This property is hidden within Visual Basic® and VBScript. It is a standard property used to support enumerating collections, such as the

For Each Obj in Collection
  '
Next Obj

syntax in Visual Basic.

Example

Sub EnumBodyPartsAndXXX( iBp as CDO.IBodyPart )
  Dim iBp_local as IBodyPart
  Dim iBps as IBodyParts
  Set iBps = iBp.BodyParts
  For Each iBp_local in iBps
    ' Code here.
  Next iBp
End Sub
© 2000-2001 Microsoft Corporation. All rights reserved.


Add Method

Adds a new BodyPart object to the collection.

[Visual Basic]
Function Add([ByVal Index as Long = -1]) as IBodyPart
[C++]
HRESULT Add( long Index = -1, IBodyPart** pVal);
[IDL]
HRESULT Add(
   [in, defaultvalue(-1), optional] long Index,
   [out,retval] IBodyPart** pVal
);
Index
The ordinal index within the collection at which the new object is to be added. The first element in the collection has an index of 1, and the last element has an index equal to Count. Setting Index to 1 causes the new object to be inserted at the beginning of the collection. Setting Index to -1 causes the new object to be appended to the collection. Index settings of 0 or less than -1 are invalid.

Remarks

Index allows a BodyPart object to be inserted into a specific location in the collection.

If an object already exists in the collection with the index you specify, then that object and all following objects have their index increased by one, and the object is then inserted. Insertion with the Add method does not replace the object at the index you specify.

The content-type for the newly added BodyPart object defaults to "application/octet-stream".

The content-disposition for the newly added BodyPart object defaults to "attachment" if the BodyParts collection contains attachments (that is, it was retrieved using an Attachments property on another object, such as the Message object). The "filename" attribute parameter, however, is not set automatically.

Example

Dim iMsg as New CDO.Message
Dim iBp as IBodyPart
Dim iBps as IBodyParts

Set iBps = iMsg.BodyPart.BodyParts
Set iBp = iBps.Add
...


Delete Method

Removes the specified BodyPart object from the collection.

[Visual Basic]
Sub Delete(Item as Variant)
[C++]
HRESULT Delete( VARIANT Item);
[IDL]
HRESULT Delete([in] VARIANT Item );
Item
Either the ordinal index or the IBodyPart interface on the object to remove from the collection.

Remarks

You can delete the object by specifying its position in the collection, or by passing the IBodyPart interface to the Delete method.

Example

Dim iMsg as New CDO.Message
Dim iBp as IBodyPart
Dim iBps as IBodyParts
Set iBps = iMsg.BodyPart.BodyParts
Set iBp = iBps.Add
... '  add more body parts
iBps.Delete iBp  ' delete this specific object
iBps.Delete 2    ' delete object # 2


DeleteAll Method

Removes all BodyPart objects from the collection.

[Visual Basic]
Sub DeleteAll()
[C++]
HRESULT DeleteAll();
[IDL]
HRESULT DeleteAll();

Example

Dim iMsg as New CDO.Message
Dim iBp as IBodyPart
Dim iBps as IBodyParts
Set iBps = iMsg.BodyPart.BodyParts
Set iBp = iBps.Add
... '  add more body parts
iBps.DeleteAll


ICalendarMessage Interface

Use the ICalendarMessage interface to create and process meeting requests.

IID
CD000122-8B95-11D1-82DB-00C04FB1625D
Extends
IDispatch

Member Summary

Properties

Name | Type | Description
CalendarParts (Read-only) | [Visual Basic,VBScript] ICalendarParts [C++,IDL] ICalendarParts* | Returns the ICalendarParts interface on the implementing object, obtaining a collection of all calendar parts in a message. The calendar parts obtained can be within the same body part or from different body parts in a message.
Configuration | IConfiguration IConfiguration* | A reference to a Configuration object. This object defines the messaging configuration used by the CalendarMessage object.
DataSource (Read-only) | IDataSource [C++,IDL] IDataSource* | Returns the IDataSource interface on the object.
Message (Read-only) | IMessage [C++,IDL] IMessage* | Returns the IMessage interface on this object.

Methods

Name | Description
GetInterface | Returns a specified interface on this object. Acts as a QueryInterface or Set method for scripting languages.


CalendarParts Property

Returns the ICalendarParts interface on the implementing object.

The ICalendarParts interface is used to obtain the calendar parts in a message being processed. This interface can also be used to add multiple appointments to a meeting request being created.

The calendar parts can be within the same body part or from different body parts in a message.

[Visual Basic,VBScript]
Property CalendarParts As ICalendarParts
read-only
[C++]
HRESULT get_CalendarParts(ICalendarParts** pVal);
[IDL]
HRESULT [propget] CalendarParts([out,retval] ICalendarParts** pVal);


Configuration Property

Sets or returns a Configuration object for a calendar message.

[Visual Basic,VBScript]
Property Configuration As IConfiguration
[C++]
HRESULT get_Configuration(IConfiguration** pVal);
HRESULT put_Configuration(IConfiguration* Val);
[IDL]
HRESULT [propget] Configuration([out,retval] IConfiguration** pVal);
HRESULT [proput] Configuration([in] IConfiguration* Val);


DataSource Property

Returns the IDataSource interface on the object.

[Visual Basic,VBScript]
Property DataSource as IDataSource
read-only
[C++]
HRESULT get_DataSource(IDataSource** pVal);
[IDL]
HRESULT [propget] DataSource([out,retval] IDataSource** pVal);

Remarks

This property returns the IDataSource interface on the object. You can use the IDataSource interface to open and save items in the store.

If the object does not implement the IDataSource interface, the COM exception E_NOTIMPL is raised.


Message Property

Returns the IMessage interface on this object. This property enables you to use all of the methods and properties of the IMessage interface with a CalendarMessage object.

[Visual Basic,VBScript]
Property Message As IMessage
read-only
[C++]
HRESULT get_Message(IMessage** pVal);
[IDL]
HRESULT [propget] Message([out,retval] IMessage** pVal);

Remarks

This property returns the IMessage interface on the object. It also serves as shorthand for standard interface navigation techniques such as QueryInterface in C++, Set in Microsoft® Visual Basic®, casting in Java, and the IMessage::GetInterface method used by scripting languages.


GetInterface Method

Returns the specified dual interface on the object.

[Visual Basic,VBScript]
Function GetInterface(ByVal Interface as String) as Object
[C++]
HRESULT GetInterface( BSTR Interface, IDispatch** ppUnknown);
[IDL]
HRESULT GetInterface([in] BSTR Interface, [out,retval] IDispatch** ppUnknown);
Interface
The name of the interface to obtain. The list of possible interfaces to return depends upon the COM class that provides the implementation.
ppUnknown [C++,IDL]
If the method succeeds, then on return, the address passed holds a reference to the requested interface.

Remarks

The GetInterface method is primarily intended as a generic interface navigation aid to scripting languages that do not support such navigation directly. Most COM classes that provide implementations of the IMessage interface expose additional dual interfaces that are accessible by scripting languages only through properties on the interface, such as BodyPart and DataSource, or through using the GetInterface method. When properties do not exist on the interface to return these interfaces, the GetInterface method must be used.

The list of valid interface names to pass to GetInterface depends upon a specific implementation. As a general rule, the name of the desired interface should match the physical name of the interface as it appears in the type library or .idl file. Check the appropriate COM class for a list of exposed dual interfaces. If the object does not support the requested interface, an exception is raised with the HRESULT value of E_INVALIDARG.

Example

[VBScript]
Dim iCalMsg
Set iCalMsg = CreateObject("CDO.CalendarMessage")
Dim iDsrc
Set iDsrc = iCalMsg.GetInterface("IDataSource")


ICalendarPart Interface

Provides access to a body part of calendar content on a calendar message object.

IID
CD000133-8B95-11D1-82DB-00C04FB1625D
Extends
IDispatch

Member Summary

Properties

Name | Type | Description
CalendarMethod (Read-only) | [Visual Basic,VBScript]String [C++,IDL] BSTR | Returns the type of calendar action, such as a meeting request.
CalendarVersion (Read-only) | [Visual Basic,VBScript] String [C++,IDL] BSTR | Returns the version of the iCalendar standard for a meeting request.
ComponentType (Read-only) | [Visual Basic,VBScript] CdoComponentType [C++,IDL] CdoComponentType | Returns the calendar part type, such as an appointment.
ProdID (Read-only) | [Visual Basic,VBScript] String [C++,IDL] BSTR | Returns the product identifier.

Methods

Name | Description
GetAssociatedItem | Returns an Appointment object for the appointment in the Microsoft® Web Storage System with the same identifier (UID) as the appointment in the calendar part.
GetInterface | Returns a specified interface on this object. Acts as a QueryInterface or Set method for scripting languages.
GetUpdatedItem | Returns the Appointment object that contains the latest updated version of an appointment.


CalendarMethod Property

Returns the type of calendar action, such as a meeting request.

[Visual Basic,VBScript]
Property CalendarMethod As String
read-only
[C++]
HRESULT get_DescriptionURL(BSTR* pVal);
[IDL]
HRESULT [propget] CalendarMethod([out,retval] BSTR* pVal);

Remarks

Use the constant values in CdoMethodValues:

Constant | Value
cdoAdd | Add
cdoCancel | Cancel
cdoCounter | Counter
cdoDeclineCounter | DeclineCounter
cdoPublish | Publish
cdoRefresh | Refresh
cdoReply | Reply
cdoRequest | Request


CalendarVersion Property

Returns the version of the iCalendar standard for an appointment.

[Visual Basic,VBScript]
Property CalendarVersion As String
read-only
[C++]
HRESULT get_CalendarVersion(BSTR* pVal);
[IDL]
HRESULT [propget] CalendarVersion([out,retval] BSTR* pVal);


ComponentType Property

Returns the calendar part type, such as an appointment.

[Visual Basic,VBScript]
Property ComponentType As String
read-only
[C++]
HRESULT get_ComponentType(BSTR* pVal);
[IDL]
HRESULT [propget] ComponentType([out,retval] BSTR* pVal);

Remarks

Use the values from the CdoComponentType enumeration.


ProdID Property

Returns a product identifier.

[Visual Basic,VBScript]
Public Property ProdID As String
read-only
[C++]
HRESULT get_ProdID(BSTR* pVal);
[IDL]
HRESULT [propget] ProdID([out,retval] BSTR* pVal);


GetAssociatedItem Method

Returns an Appointment object that contains the appointment in the Web Storage System that has the same identifier (UID) as the appointment in the calendar part. If no appointment in the Web Storage System has the same UID as the calendar part, the method returns an error.

[Visual Basic,VBScript]
Function GetAssociatedItem(
  [CalendarLocation as String],
  [UserName as String],
  [Password as String]
  ) As IAppointment
[C++]
HRESULT GetAssociatedItem(
  BSTR CalendarLocation,
  BSTR UserName,
  BSTR Password,
  IAppointment** pVal
  );
[IDL]
HRESULT GetAssociatedItem(
  [in,optional]BSTR CalendarLocation,
  [in,optional]BSTR UserName,
  [in,optional]BSTR Password,
  [out,retval] IAppointment** pVal);
CalendarLocation
The location of the calendar folder.
UserName
A user who has read/write permission to the folder specified by the CalendarLocation parameter.
Password
The user's password.

Remarks

For calendar folders in the private store, the format of the CalendarLocation string is:

"file://./backofficestorage/<domain_name>/<private_store>/<user_name>/calendar/"

This method does not return any information from the appointment in the calendar part.

If the calendar location is not specified in the method parameters, CDO uses the calendar location from the Configuration object. The following code sets the calendar location field in the Configuration object:

[Visual Basic]
Dim Config    As New Configuration
Config.Fields("CalendarLocation") = "file://./backofficestorage/domain/MBX/user/calendar"
Config.Fields.Update

Note These examples use a file URL with the Exchange OLE DB (ExOLEDB) provider. The ExOLEDB provider also supports the HTTP URL scheme.


GetInterface Method

Returns the specified dual interface on the object.

[Visual Basic,VBScript]
Function GetInterface(ByVal Interface as String) as Object
[C++]
HRESULT GetInterface( BSTR Interface, IDispatch** ppUnknown);
[IDL]
HRESULT GetInterface([in] BSTR Interface, [out,retval] IDispatch** ppUnknown);
Interface
The name of the interface to obtain. The list of possible interfaces to return depends upon the COM class that provides the implementation.
ppUnknown [C++,IDL]
If the method succeeds, then on return, the address passed holds a reference to the requested interface.

Remarks

The GetInterface method is primarily intended as a generic interface navigation aid for scripting languages that do not support such navigation directly. Most COM classes that provide implementations of the IMessage interface expose additional dual interfaces that are accessible by scripting languages only through properties on the interface, such as BodyPart and DataSource. When the interface does not have properties to return these interfaces, use the GetInterface method.

The list of valid interface names to pass to GetInterface depends upon a specific implementation. As a general rule, the name of the desired interface should match the physical name of the interface as it appears in the type library or .idl file. Check the appropriate COM class for a list of exposed dual interfaces. If an object does not support the requested interface, an exception is raised with the HRESULT value of E_INVALIDARG.

Example

[VBScript]
Dim iAppt
Set iAppt = iCalPart.GetInterface("IAppointment")


GetUpdatedItem Method

Returns the Appointment object that contains the latest updated version of a meeting. This method is used to process updates to meetings and meeting responses.

If the Microsoft® Web Storage System contains a meeting with the same identifier (UID) as the meeting in the calendar part, this method returns the meeting that was updated most recently. If no meeting in the Web Storage System has the same UID as the meeting in the calendar part, this method returns the meeting from the calendar part.

When you save the meeting returned by this method, it overwrites the meeting in the Web Storage System.

Note If the calendar part contains an exception to an existing recurring meeting, the GetUpdatedItem method returns the exception in memory. If you accept or decline the exception, the meeting response is based on the exception. However, when you call the IDataSource.Save method on the exception, it merges the exception into the master recurring meeting and saves the updated master to the Web Storage System.

[Visual Basic,VBScript]
Function GetUpdatedItem(
  [CalendarLocation as String],
  [UserName as String],
  [Password as String]
  ) As IAppointment
[C++]
HRESULT GetUpdatedItem(
  BSTR CalendarLocation,
  BSTR UserName,
  BSTR Password,
  IAppointment** pVal
  );
[IDL]
HRESULT GetUpdatedItem(
  [in,optional]BSTR CalendarLocation,
  [in,optional]BSTR UserName,
  [in,optional]BSTR Password,
  [out,retval] IAppointment** pVal);
CalendarLocation
The location of the calendar folder.
UserName
A user who has read/write permission to the folder specified by the CalendarLocation parameter.
Password
The user's password.

Remarks

For calendar folders in the private store, the format of the CalendarLocation string is:

"file://./backofficestorage/<domain_name>/<private_store>/<user_name>/calendar/"

If the calendar location is not specified in the method parameters, CDO uses the calendar location from the Configuration object. The following code sets the calendar location field in the Configuration object:

[Visual Basic]
Dim Config    As New Configuration
Config.Fields("CalendarLocation") = "file://./backofficestorage/domain/MBX/user/calendar"
Config.Fields.Update

Note These examples use a file URL with the Exchange OLE DB (ExOLEDB) provider. The ExOLEDB provider also supports the HTTP URL scheme.


ICalendarParts Interface

Defines properties and methods that enable access to a collection of CalendarPart COM objects.

When you create a meeting request, you can use the ICalendarParts interface to add multiple appointments to a single meeting request. When you process a received meeting request, you need to use the ICalendarParts interface to access each appointment, contained in a CalendarPart object, in the meeting request.

IID
CD000130-8B95-11D1-82DB-00C04FB1625D
Extends
IDispatch

Member Summary

Properties

Name | Type | Description
Count (Read-only) | [Visual Basic,VBScript]Long [C++,IDL] long | Returns the number of CalendarPart objects in the collection.
Item (Read-only) | [Visual Basic,VBScript] ICalendarPart [C++,IDL] ICalendarPart* | Returns a reference to an object at a given index in the collection.
_NewEnum (Read-only) | [Visual Basic,VBScript] (Used in For Each In) [C++,IDL] IUnknown* | Returns an IEnumVariant interface on an enumeration object. (This property is hidden from Microsoft® Visual Basic® and is used in For Each in constructs.)

Methods

Name | Description
Add | Adds a CalendarPart object to the collection.
Delete | Removes the specified Calendar object from the collection.

Remarks

The collection index always ranges from 1 to the value returned by the Count property.


Count Property

Returns the number of CalendarPart objects in the collection.

[Visual Basic,VBScript]
Property Count as Long
read-only
[C++]
HRESULT get_Count(long* pVal);
[IDL]
HRESULT [propget] Count([out,retval] long* pVal);


Item Property

Returns the CalendarPart object specified by the index.

[Visual Basic,VBScript]
Property Item(ByVal Index as Long) as ICalendarPart
read-only
[C++]
HRESULT get_Item(long* Index, ICalendarPart** pVal);
[IDL]
HRESULT [propget] Item([in] long Index, [out,retval] ICalendarPart** pVal);

Remarks

Item is the default member on the interface. The collection index always ranges from 1 to the value returned by the Count property.


_NewEnum Property

Returns an IEnumVariant interface on an enumeration object for the collection. This property is hidden from Microsoft® Visual Basic® and Microsoft® Visual Basic® Scripting Edition (VBScript).

[Visual Basic,VBScript]
Used automatically in For Each In constructs
[C++]
HRESULT get__NewEnum(IUnknown** pVal);
[IDL]
HRESULT [propget] _NewEnum([out,retval] IUnknown** pVal);

Remarks

This property is hidden within Visual Basic and VBScript. It is a standard property used to support enumerating collections, such as the

For Each in

construct in Visual Basic.

Example

[Visual Basic]
Dim iCalPart as ICalendarPart
Dim iCalParts as ICalendarParts
...
For Each iCalPart in iCalendarParts   ' _NewEnum used internally here
...
Next iCalPart
© 2000-2001 Microsoft Corporation. All rights reserved.


Add Method

Adds a new CalendarPart object to the collection.

[Visual Basic,VBScript]
Sub Add(CalendarPart As Unknown, ComponentType As CdoComponentType)
[C++]
HRESULT Add(IUnknown* CalendarPart, CdoComponentType ComponentType);
[IDL]
HRESULT Add([in] IUnknown* CalendarPart, [in] CdoComponentType ComponentType);
CalendarPart
A reference to a CalendarPart object.
CdoComponentType
The type of CDO component from the CdoComponentType enumeration.


Delete Method

Removes the specified CalendarPart object from the collection.

[Visual Basic,VBScript]
Sub Delete(Index as Long)
[C++]
HRESULT Delete(long* Index);
[IDL]
HRESULT Delete([in] LONG Index);
Index
The ordinal index of the CalendarPart object within the collection to remove.

Remarks

The collection index always ranges from 1 to the value returned by the Count property.


IConfiguration Interface

The IConfiguration interface defines properties and methods used to access configuration information for CDO objects.

IID
CD000022-8B95-11D1-82DB-00C04FB1625D
Extends
IDispatch

Member Summary

Properties

Name | Type | Description
Fields (Read-only) | [Visual Basic]ADODB.Fields [C++,IDL] Fields* | The Fields collection for the object.

Methods

Name | Description
Load | Loads the specified configuration.
GetInterface | Returns the requested dual interface on the object.

Remarks

You can access configuration settings on implementing objects using the IConfiguration interface. The Fields property references an ADO Fields collection, and each Field object in the collection contains a name/value pair that defines some part of a particular configuration. Consult the appropriate fields section of the reference for a list of valid fields to use. Most field names associated with configuration settings reside in the http://schemas.microsoft.com/cdo/configuration/ namespace.

Example

The following example demonstrates the use of the IConfiguration interface on a CDO Configuration object. When sending messages from a machine that does not have an SMTP service installed, we must send the message using an SMTP service on the network. A Configuration object is created, populated with configuration information and then associated with a Message object using the IMessage.Configuration property. The SMTP server name, port, user display name, e-mail address, and credentials are all set as a part of the configuration. The table below lists the values used. Note that a field's fully qualified name must be used when referring to it. For configuration fields, all field names are prefixed with the http://schemas.microsoft.com/cdo/configuration/ namespace. For example, the fully qualified name for the smtpserver field is http://schemas.microsoft.com/cdo/configuration/smtpserver. The namespace prefix is not shown in the table below to preserve space.

Namespace: http://schemas.microsoft.com/cdo/configuration/

Field | Value
smtpserver | mail.microsoft.com
smtpserverport | 67
smtpaccountname | My Name
sendemailaddress | "Some One" <someone@microsoft.com>
smtpauthenticate | cdoBasic (1)
sendusername | domain\username
sendpassword | password
smtpusessl | True (VARIANT_TRUE)
sendusing | cdoSendUsingPort (2)

Once the Configuration object has been populated with relevant configuration information, and associated with the Message object, the message is sent. It the examples below, the CdoConfiguration module constants are used to identify the desired field. These constants are simply the full names of the fields in the namespace. For example, the CdoConfiguration constant cdoSMTPServer is equal to the string http://schemas.microsoft.com/cdo/configuration/smtpserver.

[Visual Basic]
Dim iConf as new CDO.Configuration
Dim Flds as ADODB.Fields

Set Flds = iConf.Fields
Flds(cdoSendUsingMethod)          = cdoSendUsingPort ' 2
Flds(cdoSMTPServer)               = "mail.microsoft.com"
Flds(cdoSMTPServerPort)           = 67
Flds(cdoSMTPAccountName)          = "My Name"
Flds(cdoSMTPAuthenticate)         = cdoBasic ' 1
Flds(cdoSendUserName)             = "domain\username"
Flds(CdoSendPassword)             = "password"
Flds(cdoSendEmailAddress)         = """MySelf"" <myself@microsoft.com>"
Flds(cdoSMTPUseSSL)               = True
Flds.Update

Dim iMsg as New CDO.Message
Set iMsg.Configuration = iConf
  ' ... compose message; add attachments, etc
iMsg.Send
[C++,IDL]
#import "c:\program files\common files\system\ado\msado15.dll" no_namespace raw_interfaces_only
#import "c:\winnt\system32\cdosys.dll" no_namespace raw_interfaces_only
#include "cdosysstr.h"
#include "cdosyserr.h"
#include <atlbase.h>
#include <atlimpl.cpp>

main( ){

  CoInitialize(NULL);
  HRESULT hr = S_OK;
  {
    // Create Configuration Object
    CComPtr<IConfiguration> pConf;
    hr = pConf.CoCreateInstance(L"CDO.Configuration");

    CComPtr<Fields> pFields;
    hr = pConf->get_Fields(&pflds);

     CComPtr<Field> pfld;
     hr = pFields->get_Item(CComVariant(cdoSMTPServer),&pfld);
     hr = pfld->put_Value(CComVariant("mailserver"));

     hr = pFields->get_Item(CComVariant(cdoSMTPServerPort),&pfld);
     hr = pfld->put_Value(CComVariant((long)67));

     hr = pFields->get_Item(CComVariant(cdoSMTPAccountName),&pfld);
     hr = pfld->put_Value(CComVariant("My Name"));

     hr = pFields->get_Item(CComVariant(cdoSendEmailAddress),&pfld);
     hr = pfld->put_Value(CComVariant("\MySelf\" <myself@microsoft.com>"));

     hr = pFields->get_Item(CComVariant(cdoSTMPAuthenticate),&pfld);
     hr = pfld->put_Value(CComVariant((long)cdoBasic));

     hr = pFields->get_Item(CComVariant(cdoSendUserName),&pfld);
     hr = pfld->put_Value(CComVariant("domain\\username"));

     hr = pFields->get_Item(CComVariant(cdoSendPassword),&pfld);
     hr = pfld->put_Value(CComVariant("password"));

     hr = pFields->get_Item(CComVariant(cdoSMTPUseSSL),&pfld);
     hr = pfld->put_Value(CComVariant(VARIANT_TRUE));

    hr = pFields->get_Item(CComVariant(cdoSendUsingMethod),&pfld);
    hr = pfld->put_Value(CComVariant((long)cdoSendUsingPort));

    hr = pFields->Update();

    CComPtr<IMessage> pMsg;
    pMsg.CoCreateInstance(L"CDO.Message");
    pMsg->putref_Configuration(pConf);

    // ... compose message; add attachments, etc

    pMsg->Send();

  }
  CoUninitialize();
}
[Visual Basic]
Dim iConf
Set iConf = CreateObject("CDO.Configuration")
Dim Flds as ADODB.Fields
Set Flds = iConf.Fields
Flds(cdoSendUsingMethod)          = cdoSendUsingPort ' 2
Flds(cdoSMTPServer)               = "mail.microsoft.com"
Flds(cdoSMTPServerPort)           = 67
Flds(cdoSMTPAccountName)          = "My Name"
Flds(cdoSMTPAuthenticate)         = cdoBasic ' 1
Flds(cdoSendUserName)             = "domain\username"
Flds(CdoSendPassword)             = "password"
Flds(cdoSendEmailAddress)         = """MySelf"" <myself@microsoft.com>"
Flds(cdoSMTPUseSSL)               = True
Flds.Update

Dim iMsg
Set iMsg = CreateObject("CDO.Message")
Set iMsg.Configuration = iConf
  ' ... compose message; add attachments, etc
iMsg.Send


Fields Property

Returns the Fields object that contains the currently defined configuration settings.

[Visual Basic]
Property Fields as ADODB.Fields
read-only
default
[C++]
HRESULT get_Fields(Fields** pFields);
[IDL]
HRESULT [propget,id(0)] Fields([out,retval] Fields** pFields);
pFields [C++,IDL]
If the method succeeds, then on return, the passed address holds a reference to the requested interface.

Remarks

The ADO Fields object is a collection of ADO Field objects containing name/value pairs that define a configuration. The name is always a string, and the value is a VARIANT, the subtype of which depends upon the type of property.

The IConfiguration interface is normally exposed by instances of the Configuration COM class. The list of fields available for instances of the Configuration COM class can be found in the http://schemas.microsoft.com/cdo/configuration/ namespace.

The Fields property is the default property for the interface.

Note When you use the ADO Fields.Update method, field values are updated only in memory. You must call IDataSource.Save to save the changes to the Web Storage System. To get the IDataSource interface, use the GetInterface method on the CDO object.

See Also

http://schemas.microsoft.com/cdo/configuration/ namespace .


Load Method

Loads the specified configuration.

[Visual Basic]
Sub Load(ByVal LoadFrom as CdoConfigSource, [ByVal URL as String])
[C++]
HRESULT Load(CdoConfigSource LoadFrom, BSTR URL);
[IDL]
HRESULT Load([in] CdoConfigSource LoadFrom, [in, optional] BSTR URL);
LoadFrom
Specifies what configuration to load. Can be any value from the following CdoConfigSource enumeration.
Name | Value | Description
cdoSourceDefaults | -1 | Load all applicable default field values.
cdoSourceIIS | 1 | Load any default values from IIS.
cdoSourceOutlookExpress | 2 | Load default values from Outlook Express.

URL
This parameter is ignored and reserved for future use.

Remarks

Use the Load method to explicitly load (or re-load) default configuration settings. These settings can include SMTP service settings and/or Outlook Express settings. The availability of these configuration settings is dependent on the local installed software.

Example

Dim iConf as New CDO.Configuration
iConf.Load cdoSourceIIS
...
Dim iMsg as New CDO.Message
Set iMsg.Configuration = iConf
© 2000-2001 Microsoft Corporation. All rights reserved.


GetInterface Method

Returns the specified dual interface on the object.

[Visual Basic]
Function GetInterface(ByVal Interface as String) as Object
[C++]
HRESULT GetInterface( BSTR Interface, IDispatch** ppUnknown);
[IDL]
HRESULT GetInterface([in] BSTR Interface, [out,retval] IDispatch** ppUnknown);
Interface
The name of interface to obtain. The list of possible interfaces to return depends upon the COM class that provides the implementation.
ppUnknown [C++,IDL]
If the method succeeds, then on return, the passed address holds a reference to the requested interface.

Remarks

The GetInterface method is primarily intended as a generic interface navigation aid to scripting languages that do not support such navigation directly.

The list of valid interface names to pass to GetInterface is dependent upon a specific implementation. As a general rule, the name of the desired interface should match the physical name of the interface as it appears in the type library or .idl file. Check the appropriate COM class for a list of exposed dual interfaces. If the requested interface is not supported by the object, an exception is raised with the HRESULT value of E_INVALIDARG.

Example

[VBScript]

Dim iCfg

Set iCfg = CreateObject("CDO.Configuration")

Dim iDsrc

Set iDsrc = iCfg.GetInterface("IDataSource")


ICustomActivity Interface

Supports using COM objects as action table conditions, actions, or compensating actions.

IID
CD001105-8B95-11D1-82DB-00C04FB1625D
Extends
IDispatch

Member Summary

Name | Description
CompensatingAction | The workflow engine calls this method when a process instance transition gets aborted and the action table specifies a custom COM object as the compensating action. The custom COM object must implement this method.
EvaluateCondition | The workflow engine calls this method when the action table specifies a custom COM object as the condition on the matching row. The custom COM object must implement this method.
ExecuteAction | The workflow engine calls this method when the matching row in the action table specifies a custom COM object as the action. The custom COM object must implement this method.

Remarks

This interface needs to be implemented by any custom COM objects introduced by the workflow author. These methods correspond to the Condition, Action, and CompensatingAction fields of the action table. You specify which fields use COM objects on a per-row basis by using the Flags field on each row. Flags are set by a bitwise OR of the CdoWfTransitionFlags enumeration constants.

Only privileged-mode workflows are allowed to create COM objects.

See Also

IProcessDefinition.Mode Property

© 2000-2001 Microsoft Corporation. All rights reserved.


CompensatingAction Method

The workflow engine calls this method when a process instance transition gets aborted and the action table specifies a custom COM object as the compensating action. The custom COM object must implement this method.

[Visual Basic,VBScript]
Sub CompensatingAction(pSession as WorkflowSession)
[C++]
HRESULT _stdcall CompensatingAction(IWorkflowSession* pSession);
[IDL]
HRESULT _stdcall CompensatingAction([in] IWorkflowSession* pSession);

Remarks

When your action table includes the ProgID of a custom COM object as a compensating action, the workflow engine creates an instance of your COM object and calls the CompensatingAction method that your COM object has implemented. COM objects can only be created in privileged-mode workflows, so the engine checks to see if this ProcessInstance belongs to a privileged-mode workflow.

Example

In order to use this interface, you need to create your own COM object. If you implemented the following code in a dynamic link library and used the ProgID of your DLL in the CompensatingAction field of a row in your workflow action table, when the workflow engine used that row the following CompensatingAction would execute for an aborted ProcessInstance transition:

  • Send a message from the workflow user to the workflow user with the subject Compensating Action and the text <currentstate> -> <newstate>.
[Visual Basic]
Implements CDOWF.ICustomActivity

Sub SendMail(MySubject, ByVal pSession As CDOWF.IWorkflowSession)

    Set MyMsg = CreateObject("CDO.Message")
    With MyMsg
       .From = pSession.Sender
       .To = "someone@microsoft.com"
       .Subject = MySubject
       .TextBody = pSession.StateFrom & " -> " & pSession.StateTo
       .Send
    End With

End Sub

Sub ICustomActivity_CompensatingAction(ByVal pSession As CDOWF.IWorkflowSession)

    SendMail "Compensating Action", pSession

End Sub

Function ICustomActivity_EvaluateCondition(ByVal pSession As CDOWF.IWorkflowSession) As Boolean

    ICustomActivity_EvaluateCondition = True

End Function

Sub ICustomActivity_ExecuteAction(ByVal pSession As CDOWF.IWorkflowSession)

End Sub

See Also

IProcessDefinition.Mode Property

ICustomActivity Interface

© 2000-2001 Microsoft Corporation. All rights reserved.


EvaluateCondition Method

The workflow engine calls this method when the action table specifies a custom COM object as the condition on the matching row. The custom COM object must implement this method.

[Visual Basic,VBScript]
Function EvaluateCondition(pSession as WorkflowSession)As Boolean
[C++]
HRESULT _stdcall EvaluateCondition(IWorkflowSession* pSession, VARIANT_BOOL* pResult);
[IDL]
HRESULT _stdcall EvaluateCondition([in] IWorkflowSession* pSession, [out] VARIANT_BOOL* pResult);

Remarks

When your action table includes the ProgID of a custom COM object as a condition, the workflow engine creates an instance of your COM object and calls the EvaluateCondition method that your COM object has implemented. COM objects can only be created in privileged-mode workflows, so the engine checks to see if this ProcessInstance belongs to a privileged-mode workflow.

Example

In order to use this interface, you need to create your own COM object. If you implemented the following code in a dynamic link library and used the ProgID of your DLL in the Condition field of a row in your workflow action table, when the workflow engine used that row the following Condition would execute:

  • Return true.
[Visual Basic]
Implements CDOWF.ICustomActivity

Sub ICustomActivity_CompensatingAction(ByVal pSession As CDOWF.IWorkflowSession)

End Sub

Function ICustomActivity_EvaluateCondition(ByVal pSession As CDOWF.IWorkflowSession) As Boolean

    ICustomActivity_EvaluateCondition = True

End Function

Sub ICustomActivity_ExecuteAction(ByVal pSession As CDOWF.IWorkflowSession)

End Sub

See Also

IProcessDefinition.Mode Property

ICustomActivity Interface

© 2000-2001 Microsoft Corporation. All rights reserved.


ExecuteAction Method

The workflow engine calls this method when the matching row in the action table specifies a custom COM object as the action. The custom COM object must implement this method.

[Visual Basic,VBScript]
Sub ExecuteAction(pSession as WorkflowSession)
[C++]
HRESULT _stdcall ExecuteAction(IWorkflowSession* pSession);
[IDL]
HRESULT _stdcall ExecuteAction([in] IWorkflowSession* pSession);

Remarks

When your action table includes the ProgID of a custom COM object as an action, the workflow engine creates an instance of your COM object and calls the ExecuteAction method that your COM object has implemented. COM objects can only be created in privileged-mode workflows, so the engine checks to see if this ProcessInstance belongs to a privileged-mode workflow.

Example

In order to use this interface, you need to create your own COM object. If you implemented the following code in a dynamic link library and used the ProgID of your DLL in the Action field of a row in your workflow action table, when the workflow engine used that row the following action would execute:

  • Send a message from the workflow user to the workflow user with the subject OnCreate Event and the text <currentstate> -> <newstate>.
  • Post "WorkflowSession AuditTrail AddEntry is working" to the Event Log.
  • Append a field to the ProcessInstance object representing the current state.
[Visual Basic]
Implements CDOWF.ICustomActivity

Sub SendMail(MySubject, ByVal pSession As CDOWF.IWorkflowSession)

    Set MyMsg = CreateObject("CDO.Message")
    With MyMsg
       .From = pSession.Sender
       .To = "someone@microsoft.com"
       .Subject = MySubject
       .TextBody = pSession.StateFrom & " -> " & pSession.StateTo
       .Send
    End With

End Sub

Sub ICustomActivity_CompensatingAction(ByVal pSession As CDOWF.IWorkflowSession)

End Sub

Function ICustomActivity_EvaluateCondition(ByVal pSession As CDOWF.IWorkflowSession) As Boolean

End Function

Sub ICustomActivity_ExecuteAction(ByVal pSession As CDOWF.IWorkflowSession)

    Dim FieldType
    Dim CurrentState
    CurrentState = ""
    FieldType = 8 ' BSTR
    SendMail "OnCreate Event", pSession

    pSession.AuditTrail.AddEntry "WorkflowSession AuditTrail AddEntry is working"
    CurrentState = pSession.Record.fields("http://schemas.microsoft.com/cdo/workflow/currentstate").Value
    If CurrentState <> "" Then
        pSession.Record.fields.Append CStr(CurrentState), FieldType, , , CStr(CurrentState)
        pSession.Record.fields.Update
    End If

End Sub

See Also

IProcessDefinition.Mode Property

ICustomActivity Interface

© 2000-2001 Microsoft Corporation. All rights reserved.


IDataSource Interface

The IDataSource interface defines methods and properties used to provide access to content in other objects or in the Microsoft Exchange 2000 Web Storage System.

IID
CD000029-8B95-11D1-82DB-00C04FB1625D
Extends
IDispatch

Member Summary

Properties

Name | Type | Description
ActiveConnection (Read-Only) | [Visual Basic,VBScript] ADODB.Connection [C++,IDL] _Connection* | Returns the active ADO Connection object if applicable.
IsDirty | [Visual Basic,VBScript] Boolean [C++,IDL] VARIANT_BOOL | Specifies whether the local data has been changed since the last data source binding or call to Save.
Source (Read-Only) | [Visual Basic,VBScript] Object [C++,IDL] IUnknown* | Returns the interface on the currently bound object.
SourceClass (Read-Only) | [Visual Basic,VBScript] String [C++,IDL] BSTR | Returns the string identifier of the interface used to open the object.
SourceURL (Read-Only) | [Visual Basic,VBScript] String [C++,IDL] BSTR | Returns the URL of the currently bound object if applicable.

Methods

Name | Description
Open | Binds to and opens the existing item specified by URL.
OpenObject | Binds to and opens the specified object.
Save | Saves the current data into the currently bound data source.
SaveTo | Binds to and saves data into the item specified by URL.
SaveToContainer | Binds to and saves data into a new item in the folder specified by URL. The item name is a generated globally unique identifier (GUID).
SaveToObject | Binds to and saves data into the specified object.

Remarks

Objects expose implementations of the IDataSource interface to facilitate easy access to content (data) in other CDO, ADO and Active Directory objects, and items in the Microsoft Exchange 2000 Web Storage System. For example, the Message object exposes an implementation of the IDataSource interface.

There are two aspects associated with using the IDataSource interface on objects:

  • Binding certain methods create an association, or linkage between the target item or object and the binding object. For example, when you use the Open method, you bind to a resource in the Web Storage System or Active Directory. This binding (association) remains active until the object is subsequently rebound, unbound, or destroyed. While bound, various operations such as Save or IsDirty act on (or in relation to) the currently bound resource or object.
  • Directional Transfer of Data Methods on the IDataSource are verbs that imply a direction of data flow. After binding to an object, these operations are then carried out. For example, the OpenObject method first binds the specified object, and then retrieves the serialized content contained within the bound object into the opening object. The process is analogous for the Open method. The SaveToObject, SaveTo, and SaveToContainer methods first bind to the specified object or resource, and then transfer local content into the target.

Opening other objects and resources is completely analogous to using Microsoft® Word to open its .doc files: when you "Open" a .doc file, the file is "bound" and the contents copied into the opening application. Subsequent "Save" commands overwrite the file contents with the local copy of data. When another file is opened or the user chooses Save As, the application rebinds to the new file and the appropriate data transfer occurs, either to or from the acting application. Save commands now act on the newly bound file. When a user closes the application, local data changes may not have been saved into the currently bound file. A dialog appears, "Do you wish to save the changes you have made to file?" Changes will be lost if they are not saved.

This reference only lists the loose semantic definition and COM interface binary signature required for an implementation of the IDataSource interface. For specific information about a particular implementation, see the corresponding COM class reference page.

Example

[Visual Basic]
' Reference to Microsoft CDO for Exchange 2000 Library
' Reference to Microsoft ActiveX Data Objects 2.5 Library

Function MoveItems(folderUrl1 As String, folderUrl2 As String)

    ' Items must be in same store for this routine to work
    Dim Item As New CDO.Item
    Dim Fldr As New CDO.Folder
    Dim Msg As New CDO.message
    Dim CalMsg As New CDO.CalendarMessage
    Dim iAppt  As New CDO.Appointment
    Dim Per As New CDO.Person

    Dim Rec As New ADODB.Record
    Dim Rec2 As New ADODB.Record
    Dim Rs  As New ADODB.Recordset
    Dim Conn As New ADODB.Connection

    Conn.Provider = "ExOLEDb.DataSource"
    Conn.Open folderUrl1

    Rec.Open folderUrl1, Conn
    ' Error check here

    ' This is very expensive for very large folders!
    Set Rs = Rec.GetChildren
    While Not Rs.EOF
        Rec2.Open Rs, Conn, adModeReadWrite, adFailIfNotExists
        Select Case Rec2.Fields("DAV:contentclass")
            Case "urn:content-classes:message":
                Debug.Print "Message"
                Msg.DataSource.OpenObject Rec2, "_Record"
                Debug.Print "To: " & Msg.To
                Debug.Print "From:: " & Msg.From
                Debug.Print "Subject: " & Msg.Subject
                Debug.Print vbCrLf & Msg.TextBody
                Debug.Print vbCrLf & Msg.Attachments.Count & " Attachments"
                Msg.DataSource.SaveToContainer folderUrl2, Conn, adModeReadWrite, adCreateNonCollection
                Rec2.DeleteRecord
                Rec2.Close

            Case "urn:content-classes:document":
                Debug.Print "Document"
                Item.DataSource.OpenObject Rec2, "_Record"
                Debug.Print Item.DisplayName
                Debug.Print Item.CreationDate
                Debug.Print Item.ContentClass
                ' This step MIME-encodes the document in the new location.
                'Item.DataSource.SaveToContainer folderUrl2, Conn, adModeReadWrite, adCreateNonCollection
                Item.DataSource.SaveTo folderUrl2 & "/" & Item.DisplayName, Conn, adModeReadWrite, adCreateNonCollection
                Rec2.DeleteRecord
                Rec2.Close

            Case "urn:content-classes:folder":
                Debug.Print "Folder"
                Fldr.DataSource.OpenObject Rec2, "_Record"
                Debug.Print Fldr.DisplayName
                Debug.Print Fldr.ContentClass
                Debug.Print "Email address: " & Fldr.EmailAddress
                ' Must Recurse here
                Dim strOrigFolder As String
                strOrigFolder = Fldr.DataSource.SourceURL
                Fldr.DataSource.SaveTo folderUrl2 & "/" & Fldr.DisplayName, Conn, adModeReadWrite, adCreateCollection
                MoveItems strOrigFolder, Fldr.DataSource.SourceURL
                Rec2.DeleteRecord
                Rec2.Close

            Case "urn:content-classes:calendarmessage":
                Debug.Print "CalendarMessage"
                CalMsg.DataSource.OpenObject Rec2, "_Record"
                Debug.Print "To: " & CalMsg.message.To
                Debug.Print "From:: " & CalMsg.message.From
                Debug.Print "Subject: " & CalMsg.message.Subject
                Debug.Print vbCrLf & CalMsg.message.TextBody
                Debug.Print vbCrLf & CalMsg.CalendarParts.Count & " Calendar-related body parts."
                Debug.Print vbCrLf & CalMsg.message.Attachments.Count & " Attachments."
                CalMsg.DataSource.SaveToContainer folderUrl2, Conn, adModeReadWrite, adCreateNonCollection
                Rec2.DeleteRecord
                Rec2.Close

            Case "urn:content-classes:person":
                Debug.Print "Contact Item"
                Per.DataSource.OpenObject Rec2, "_Record"
                Debug.Print Per.FirstName
                Debug.Print Per.LastName
                Debug.Print Per.Company
                Debug.Print Per.Email
                Per.DataSource.SaveToContainer folderUrl2, Conn, adModeReadWrite, adCreateNonCollection
                Rec2.DeleteRecord
                Rec2.Close

        End Select

        If Rec2.State = adStateOpen Then
            Rec2.Close
        End If
        Rs.MoveNext
    Wend

End Function
[C++,IDL]
/*
 You must have the following paths in your
 INCLUDE path.
 %CommonProgramFiles%\system\ado
 %CommonProgramFiles%\microsoft shared\cdo

*/
#ifndef _CORE_EXAMPLE_HEADERS_INCLUDED
#define _CORE_EXAMPLE_HEADERS_INCLUDED
#import <msado15.dll> no_namespace
#import <cdoex.dll> no_namespace
#include <iostream.h>
#endif

#define BUFLEN  40

void SaveEmbeddedPartsToFolder( IMessagePtr pMsgIn, bstr_t folderURL ) {

   if(pMsgIn == NULL)
      throw _com_error(E_INVALIDARG);

   IDataSourcePtr   iDsrc;
   IDataSourcePtr  iDsrcItem;
   IItemPtr      iItem(__uuidof(Item));
   IBodyPartPtr   pBp;
   IBodyPartPtr   pBp2;
   IBodyPartsPtr   pBps;
   _ConnectionPtr   pConn(__uuidof(Connection));
   _StreamPtr      pStm;
   _StreamPtr      pStm2;
   _RecordPtr      pRec;
   FieldsPtr      pFlds;
   FieldPtr      pFld;
   long         i   =   0;
   long         nbp   =   0;

   // for optional params
   _variant_t      varOpt(DISP_E_PARAMNOTFOUND,VT_ERROR);

   /*
   * use this object to extract embedded messags
   */

   pConn->Provider = "ExOLEDB.DataSource";
   try {
      pConn->Open(folderURL,bstr_t(),bstr_t(),-1);
   }
   catch(_com_error e) {
      throw e;
   }

   IMessagePtr Msg(__uuidof(Message));
   iDsrc = Msg;
   pBp  = pMsgIn;

   /*
   * fetch all bodyparts below message to scan for application/octet-stream
   *  and embedded messages message/rfc822
   *  (won't find "related" parts in MHTML formmatted messages)
   */

   pBps = pBp->BodyParts;
   nbp = pBps->Count;
   for(i=1;i<=nbp;i++) {

      pBp = pBps->Item[i];
      bstr_t MediaType;

      MediaType = pBp->ContentMediaType;
      if(MediaType == _bstr_t("message/rfc822")){

         cout << "Found an embedded message...saving" << endl;
         /*
         *  Extract Embedded Message
         *   (clears previous message out)
         */
         try {
            iDsrc->OpenObject(pBp,_bstr_t("IBodyPart"));
         }
         catch(_com_error e) {
            cerr << "Error opening message/rfc822 body part" << endl;
            throw e;
         }

         try {
            iDsrc->SaveToContainer(
                     folderURL,
                     pConn,
                     adModeReadWrite,
                     adCreateNonCollection,
                     (RecordOpenOptionsEnum) NULL,
                     bstr_t(),
                     bstr_t()
                     );
         }
         catch(_com_error e) {
            cerr << "Error saving item to container" << endl;
            throw e;
         }

         pConn = iDsrc->ActiveConnection;

         bstr_t srcURL;
         srcURL = iDsrc->SourceURL;
         cout << "Saved embedded message at " << _bstr_t(srcURL) << endl;
      }
      else if(MediaType == _bstr_t("application/msword")) {
         cout << "Found an application/msword body part" << endl;

         /*
         ** Can't use SaveToContainer here.
         ** The file will get MIME encoded.
         ** Use SaveTo instead.
         */
         GUID g;
         if(FAILED(CoCreateGuid(&g))) {
            cerr << "Error creating GUID" << endl;
            throw _com_error(E_FAIL);
         }
         wchar_t buf[BUFLEN];
         memset((void*)(wchar_t*)buf,0,BUFLEN);
         if( StringFromGUID2(g,(wchar_t*)buf,BUFLEN) == 0 ) {
            cerr << "Error getting string from GUID?" << endl;
            throw _com_error(E_UNEXPECTED);
         }
         cout << "Word file name: " << bstr_t(buf) << ".doc " << endl;
         try {
            iDsrcItem = iItem;
            iItem->Fields->Item["DAV:contentclass"]->Value = variant_t("urn:content-classes:document");
            iItem->Fields->Update();
            iDsrcItem->SaveTo(
                        folderURL + bstr_t(buf) + bstr_t(".doc"),
                        _variant_t((IDispatch*)pConn, true),
                        adModeReadWrite,
                        adCreateNonCollection,
                        adOpenSource,
                        bstr_t(),
                        bstr_t()
                        );
            pStm = iItem->GetStream();
            pStm2 = pBp->GetDecodedContentStream();
            pStm2->CopyTo(pStm,-1);
            pStm->Flush();
            // Must call save here for item. Stream is not committed to the
            // store until Save() is called.
            iDsrcItem->Save();

         }
         catch(_com_error e) {
            cerr << "Error saving word file to folder " << folderURL << endl;
            throw e;
         }
      }
   }
}
[VBScript]
' Type information must have been imported into the scripting engine,
' for example:
' <reference object="adodb.record"/>
' <reference object="cdo.message"/>
' elements in
' a Windows Scripting Host (.wsf) file.

Sub SaveEmbeddedPartsToFolder(iMsg, URL)

    Dim iMsgB
    Set iMsgB = CreateObject("CDO.Message")
    Dim iDsrcB
    Dim iFldr
    Dim iDsrcFldr
    Dim Conn
    Dim iBp
    Dim iBps
    Dim ContType

    Set Conn = CreateObject("ADODB.Connection")
    Conn.Provider = "ExOLEDB.DataSource"
    Conn.Open URL

    Set iDsrcFldr = iFldr
    iDsrcFldr.Open URL, Conn

    Set iDsrcB = iMsgB.DataSource

    Set iBp = iMsg.BodyPart
    Set iBps = iBp.BodyParts

    For Each iBp In iBps
        ContType = iBp.ContentMediaType
        If ContType = "message/rfc822" Then

            iDsrcB.OpenObject iBp, "IBodyPart"
            iDsrcB.SaveToContainer FolderURL, Conn, adModeReadWrite, adCreateOverwrite

        ElseIf ContType = "application/octet-stream" Then

            Dim Rec
            Set Rec = CreateObject("ADODB.Record")
            Dim Flds
            Dim Fld
            Dim Stm1
            Dim Stm2

            'Get some unique name based on message id, etc
            Rec.Open FolderURL & "uniquename.x", Conn, adModeReadWrite, adCreateOverwrite
            Set Flds = Rec.Fields
            ' Get Stream for resource which is accessed using -1 in Fields collection
            Set Fld = Flds.Item(-1)
            Set Stm1 = Fld.Value

            ' Get Decoded BodyPart stream
            Set Stm2 = iBp.GetDecodedContentStream
            ' Copy bodypart stream to resource stream
            Stm2.CopyTo Stm1

            ' Commit
            Stm1.Flush
            Stm1.Close
            Rec.Close

        End If
    Next
End Sub
© 2000-2001 Microsoft Corporation. All rights reserved.


ActiveConnection Property

Returns the currently active ADO Connection object.

[Visual Basic,VBScript]
Property ActiveConnection as ADODB.Connection
[C++]
HRESULT get_ActiveConnection(_Connection** pVal);
HRESULT put_ActiveConnection(_Connection* Val);
[IDL]
HRESULT [propget] ActiveConnection([out,retval] _Connection** pVal);
HRESULT [propput] ActiveConnection([in] _Connection* Val);

Remarks

This property contains the _Connection interface on an ADO Connection object associated with the currently bound data source. This Connection exists only after directly binding the object to a data source specified using a URL (using an OLE DB 2.5 Provider) with calls to IDataSource.Open, IDataSource.SaveTo and IDataSource.SaveToContainer.

An ActiveConnection object reference is not available when the object is bound to another object after using IDataSource.OpenObject or SaveToObject, even if that object has an associated Connection object. Attempting to access the ActiveConnection property in such cases will cause the exception to be raised. For example, if you use IDataSource.OpenObject to bind a CDO object to an ADO Record object that is itself currently bound to an item in the Web Storage System or Active Directory, the Record object's Connection object is not available through the IDataSource.ActiveConnection property.

Example

Note This Visual Basic example uses a file URL with the Exchange OLE DB (ExOLEDB) provider. The ExOLEDB provider also supports the HTTP URL scheme.

[Visual Basic]
' Reference to Microsoft CDO for Exchange 2000 Library
' Reference to Microsoft ActiveX Data Objects 2.5 Library

    Dim iFldr As New Folder
    Dim iDsrc As CDO.IDataSource
    Set iDsrc = iFldr

    ' Open folder:
    ' e.g. Url1 = "file://./backofficestorage/microsoft.com/MBX/useralias/"

    Dim Conn As New ADODB.Connection
    Conn.Provider = "ExOLEDB.DataSource"
    Conn.Open Url1

    iDsrc.Open Url1, Conn, adModeReadWrite

    Dim iMsg As New CDO.message
    With iMsg
        .To = "someone@microsoft.com"
        .From = "another@microsoft.com"
        .Subject = "Here is the subject"
        .TextBody = "Here is the text of the message"
    End With

    Set iDsrc = iMsg

    iDsrc.SaveTo URL1 & "/Drafts/item8.eml", _
                Conn, _
                adModeReadWrite, _
                adCreateOverwrite
[C++,IDL]
/*
 You must have the following paths in your
 INCLUDE path.
 %CommonProgramFiles%\system\ado
 %CommonProgramFiles%\microsoft shared\cdo

*/
#ifndef _CORE_EXAMPLE_HEADERS_INCLUDED
#define _CORE_EXAMPLE_HEADERS_INCLUDED
#import <msado15.dll> no_namespace
#import <cdoex.dll> no_namespace
#include <iostream.h>
#endif

void SaveMessageToDrafts(bstr_t mailboxURL, IMessagePtr pMsg) {

   IDataSourcePtr pDsrc;
   IDataSourcePtr pDsrc2;
   _ConnectionPtr pConn(__uuidof(Connection));
   IFolderPtr     pFolder(__uuidof(Folder));
   FieldsPtr      Flds;
   FieldPtr       Fld;
   variant_t      vDraftsURL;

   // for passing optional variants, we may need this
   _variant_t varOpt(DISP_E_PARAMNOTFOUND,VT_ERROR);

   pConn->Provider = "ExOLEDB.DataSource";
   try {
      pConn->Open(mailboxURL,bstr_t(),bstr_t(),-1);
   }
   catch(_com_error e) {
      throw e;
   }

   /*
   * Bind to information store root folder (private/messages)
   *  e.g. URL1 below is something like
   * "file://./backofficestorage/microsoft.com/storename/username/"
   *
   */

   cout << "Opening " << mailboxURL << endl;

   pDsrc = pFolder;

   try {
      pDsrc->Open(
         mailboxURL,
         _variant_t((IDispatch*)pConn, true),
         adModeRead,
         adFailIfNotExists,
         (RecordOpenOptionsEnum)adOpenSource,
         bstr_t(),
         bstr_t()
         );

      Flds = pFolder->Fields;
      Fld = Flds->Item[variant_t("urn:schemas:httpmail:drafts")];
      vDraftsURL = Fld->Value;
   }
   catch(_com_error e) {
      cerr << "Error opening Mailbox folder" << endl;
      throw e;
   }

      /*
      *  Get ActiveConnection for bound collection resource
      *  (root of private folders for user)
      */

   pConn = pDsrc->ActiveConnection;

   // Get IDataSource on passed message object.
   pDsrc2 = pMsg;

   /*
   * Save this message to some folder
   *    ** Use the current connection used
   *    ** to bind folder above
   */

   try {
      pDsrc2->SaveToContainer(
            bstr_t(vDraftsURL),
            _variant_t((IDispatch*)pConn, true), //Connection from Folder Bind above
            adModeReadWrite,
            adCreateNonCollection,
            (RecordOpenOptionsEnum) NULL,
            bstr_t(),
            bstr_t()
      );
   }
   catch(_com_error e) {
      cerr << "Error saving message to Drafts folder!" << endl;
      throw e;
   }

}
[VBScript]
' This example demonstrates sharing a Connection object from a
' bound CDO Folder object and a CDO Message object.
'
' Type information must have been imported into the scripting engine,
' for example:
' <reference object="adodb.record"/>
' <reference object="cdo.message"/>
' elements in
' a Windows Scripting Host (.wsf) file.

Function SaveMessageToSubFolder(iMsg, iFldr1, relNewFolderURL)

    Dim iDsrc_Msg
    Dim iDsrc_Fldr1
    Dim iDsrc_Fldr2

    Dim iFldr2
    Set iFldr2 = CreateObject("CDO.Folder")

    ' First create the new sub-folder using the currently bound Folder object's connection:
    Set iDsrc_Fldr1 = iFldr1.DataSource
    Set iDsrc_Fldr2 = iFldr2.DataSource

    On Error Resume Next
    iDsrc_Fldr2.Open iDsrc_Fldr1.SourceURL & "/" & relNewFolderURL, _
                     iDsrc_Fldr1.ActiveConnection, _
                     adModeReadWrite

    If Err.Number <> 0 Then
     ' Folder must not exist...
     Err.Clear
     Err.Number = 0
     iDsrc_Fldr2.SaveTo iDsrc_Fldr1.SourceURL & "/" & relNewFolderURL, _
                        iDsrc_Fldr1.ActiveConnection, _
                        adModeReadWrite

     If Err.Number <> 0 Then
       wscript.echo "Error creating folder: " & Err.Description
       ' Handle Error and Quit
       wscript.quit
     End If
    End If

    On Error Goto 0

    ' Save the message to the folder as say "item8.eml"
    Set iDsrc_Msg = iMsg.DataSource

    iDsrc_Msg.SaveTo iDsrc_Fldr2.SourceURL & "/item8.eml", _
                iDsrc_Fldr2.ActiveConnection, _
                adModeReadWrite, _
                adCreateOverwrite

    Set SaveMessageToSubFolder = iFldr2
End Function
© 2000-2001 Microsoft Corporation. All rights reserved.


IsDirty Property

Specifies whether or not the local data has been altered since the last save to the currently bound data source.

[Visual Basic,VBScript]
Property IsDirty as Boolean
[C++]
HRESULT get_IsDirty(VARIANT_BOOL* pVal);
HRESULT put_IsDirty(VARIANT_BOOL Val);
[IDL]
HRESULT [propget] IsDirty([out,retval] VARIANT_BOOL* pVal);
HRESULT [propput] IsDirty([in] VARIANT_BOOL Val);

Remarks

After binding to a data source such as an applicable object or to an item in the Web Storage System, there are two copies of the data: the local data, and the data at the data source. When changes are made to the local copy of the data, this flag switches to True (VARIANT_TRUE), indicating that the local copy " is dirty" when compared to the data in the data source. The IsDirty flag is reset to False (VARIANT_FALSE) whenever the local data is saved back into the bound object using IDataSource.Save. Additionally, the flag is also reset whenever the object is re-bound using the methods IDataSource.Open, IDataSource.OpenObject, IDataSource.SaveTo, IDataSource.SaveToContainer, and IDataSource.SaveToObject.

The IsDirty property does not reflect that changes have subsequently occurred to the data in a bound data source since the time it was bound.

See Also

IDataSource.Open, IDataSource.OpenObject, IDataSource.SaveTo, IDataSource.SaveToContainer, IDataSource.SaveToObject


Open Method

Binds to and opens data from the existing item specified by URL.

[Visual Basic,VBScript]
Sub Open(
  ByVal SourceURL as String,
  [ByVal ActiveConnection as Object],
  [ByVal Mode as ConnectModeEnum],
  [ByVal CreateOptions as RecordCreateOptionsEnum],
  [ByVal Options as RecordOpenOptionsEnum],
  [ByVal UserName as String],
  [ByVal Password as String]
)
[C++]
HRESULT Open(BSTR SourceURL,
  IDispatch* ActiveConnection = 0,
  ConnectModeEnum Mode,
  RecordCreateOptionsEnum CreateOptions,
  RecordOpenOptionsEnum Options,
  BSTR UserName,
  BSTR Password
);
[IDL]
HRESULT Open(
  [in] BSTR SourceURL,
  [in, defaultvalue(0)] IDispatch* ActiveConnection,
  [in, optional] ConnectModeEnum Mode,
  [in, optional] RecordCreateOptionsEnum CreateOptions,
  [in, optional] RecordOpenOptionsEnum Options,
  [in, optional] BSTR UserName,
  [in, optional] BSTR Password
);
SourceURL
Specifies the URL of the existing item to open. New items cannot be created using the Open method. Use SaveTo or SaveToContainer.
ActiveConnection (optional)
Specifies the connection to use when opening. This is a reference to an ADO Connection object. A new Connection object (session) is implicitly created if none is specified.
Mode (optional)
ADO-defined access mode enumeration. The specified value is always ORed with adModeRead (1). This means that at least read access is requested when opening an item, not that only read access is requested.
CreateOptions (optional)
Must be adFailIfNotExists. New items cannot be created using the Open method.
Options (optional)
This specifies options flag opening the source. The only supported open option is adOpenAsynch. Your setting is always ORed with adOpenSource.
UserName (optional)
Used to pass a user name if needed for authentication.
Password (optional)
Used to pass a password if needed for authentication.

Remarks

The specified URL must identify a valid URL namespace that the OLE DB 2.5 root binder can resolve to a registered provider binder. Once resolved, the URL must conform to that provider binder's URL semantics.

The Open method has an identical signature to the Open method defined by ADO interfaces such as the _Record, _Recordset, and _Stream interfaces. The IDataSource.Open method, unlike the _Record.Open or _Stream.Open, cannot be used to create new items. Therefore, the CreateOption parameter must always be set to adFailIfNotExists. The other enumerated values and their semantic definitions are defined as part of the ADO type library and documentation. Consult the Microsoft® ActiveX® Data Objects (ADO) 2.5 documentation for a list of valid enumeration values and their intended purpose. Use of various enumerated values and their intended meaning is specific to a particular OLE DB 2.5 provider.

Restrictions on what types of data can be opened and how that data is handled by an implementation of the IDataSource interface is not part of this definition. Consult the appropriate COM class reference for further information.

Example

Note This Visual Basic example uses a file URL with the Exchange OLE DB (ExOLEDB) provider. The ExOLEDB provider also supports the HTTP URL scheme.

[Visual Basic]
' Reference to Microsoft CDO for Exchange 2000 Library
' Reference to Microsoft ActiveX Data Objects 2.5 Library

    Dim iFldr As New Folder
    Dim iDsrc As CDO.IDataSource
    Dim Conn As New ADODB.Connection

    Conn.Provider = "ExOLEDB.DataSource"
    Conn.Open Url1

    Set iDsrc = iFldr

    ' Open base mailbox folder:
    ' e.g. Url1 = "file://./backofficestorage/microsoft.com/MBX/useralias/"
    iDsrc.Open Url1, Conn, adModeReadWrite

    Dim iMsg As New CDO.message
    Set iDsrc = iMsg

    iDsrc.Open Url1 & "/Drafts/item8.eml", _
                Conn, _
                adModeReadWrite
[C++,IDL]
/*
 You must have the following paths in your
 INCLUDE path.
 %CommonProgramFiles%\system\ado
 %CommonProgramFiles%\microsoft shared\cdo

*/
#ifndef _CORE_EXAMPLE_HEADERS_INCLUDED
#define _CORE_EXAMPLE_HEADERS_INCLUDED
#import <msado15.dll> no_namespace
#import <cdoex.dll> no_namespace
#include <iostream.h>
#endif

IItemPtr OpenItem(bstr_t url) {

   _bstr_t bstrEmpty("");

   IDataSourcePtr pDsrc(__uuidof(Item));
   _variant_t varOpt(DISP_E_PARAMNOTFOUND,VT_ERROR);

   _ConnectionPtr pConn(__uuidof(Connection));

   pConn->Provider = "ExOLEDB.DataSource";

   try {
      pConn->Open(url, bstr_t(),bstr_t(),-1);
   }
   catch(_com_error e) {
      throw e;
   }

   try {
      pDsrc->Open(
         url,
         variant_t( (IDispatch*)pConn, true),
         adModeRead,
         adFailIfNotExists,
         adOpenSource,
         bstr_t(),
         bstr_t()
         );
   }
   catch(_com_error e) {
      cerr << "Error opening item" << endl;
      throw e;
   }

   return pDsrc;
}
[VBScript]
<job id="idatasource_savetocontainer">
<reference object="adodb.record"/>
<reference object="cdo.message"/>
<script language="vbscript">

    Dim iMbx
    Dim iPer
    Dim iDsrc
    Dim iMsg
    Dim Conn
    Dim InfoNT
    Dim Info
    Dim sFolderUrl

    Set Info   = CreateObject("ADSystemInfo")
    Set InfoNT = CreateObject("WinNTSystemInfo")
    Set Conn   = CreateObject("ADODB.Connection")
    Set iMsg   = CreateObject("CDO.Message")
    Set iPer   = CreateObject("CDO.Person")

    iPer.DataSource.Open "LDAP://" & Info.UserName
    Set iMbx = iPer.GetInterface("IMailbox")

    Conn.Provider = "ExOLEDB.DataSource"
    Conn.Open iMbx.baseFolder

    ' ...

    Set iDsrc = iMsg.DataSource

    iDsrc.Open iMbx.Inbox & "/subject.eml", _
                Conn, _
                adModeReadWrite

    wscript.echo iMsg.From
    wscript.echo iMsg.Subject
    ' ...
</script>
</job>
© 2000-2001 Microsoft Corporation. All rights reserved.


OpenObject Method

Binds to and opens data from the specified object.

[Visual Basic,VBScript]
Sub OpenObject(ByVal Source as Object, ByVal InterfaceName as String)
[C++]
HRESULT OpenObject(IUnknown* Source, BSTR InterfaceName);
[IDL]
HRESULT OpenObject([in] IUnknown* Source, [in] BSTR InterfaceName);
Source
A reference (interface) to the object to open.
InterfaceName
A string indicating the type of interface passed in the first argument.

Remarks

Implementations of this method are intended to allow you to easily bind to and extract data from another object at run time, rather than from a particular store or database.

For example, you can use OpenObject is for manipulation of encapsulated messages. A message can contain a body part for which the ContentMediaType property is "message/rfc822". To extract the embedded message, you create a new Message object and call IDataSource.OpenObject, passing the IBodyPart reference on the BodyPart object containing the encapsulated message. This opens the contents of the encapsulated message into the new Message object. If you wish to save changes you make to this message back into the embedded location from whence it was extracted, call IDataSource.Save, and the modified message contents are saved back to the source body part.

Note Circular binding is not supported. You cannot use OpenObject to bind the same object, such as:

Set iDsrc = iSomeInterface
iDsrc.OpenObject iSomeInterface, "ISomeInterface"

If circular binding is attempted, the CDO_E_SELF_BINDING exception is raised.

After a successful binding, the IDataSource.Source is the object reference passed to the method. Avoid passing interfaces that are not OLE Automation compatible, such as Istream, if languages such as Microsoft® Visual Basic®, Microsoft® Visual J++®, and Microsoft® Visual Basic® Scripting Edition (VBScript) will attempt to access the bound source object through the Source property. If you pass interfaces that are not OLE Automation compatible, the object reference returned by the Source property will be unusable by these languages.

If the string passed as the interface type name (the InterfaceName parameter) is not recognized, the method must raise an exception.

Example

[Visual Basic]
Function GetEmbeddedMessage(iBp As CDO.IBodyPart) As CDO.message

  Dim iMsg As New CDO.message
  Dim iDsrc As CDO.IDataSource
  Set iDsrc = iMsg ' get IDataSource interface

  ' open the body part object containing an embedded message
  iDsrc.OpenObject iBp, "IBodyPart"
  Set GetEmbeddedMessage = iMsg

End Function
[C++,IDL]
/*
 You must have the following paths in your
 INCLUDE path.
 %CommonProgramFiles%\system\ado
 %CommonProgramFiles%\microsoft shared\cdo

*/
#ifndef _CORE_EXAMPLE_HEADERS_INCLUDED
#define _CORE_EXAMPLE_HEADERS_INCLUDED
#import <msado15.dll> no_namespace
#import <cdoex.dll> no_namespace
#include <iostream.h>
#endif

IMessagePtr GetEmbeddedMessage(IBodyPartPtr pBp) {

   IDataSourcePtr pDsrc;
   if(pBp == NULL)
      throw _com_error(E_POINTER);
   pDsrc.CreateInstance(__uuidof(Message));

   /*
   * Open body part that contains message/rfc822 content
   */

   pDsrc->OpenObject(pBp, _bstr_t("IBodyPart"));
   IMessagePtr pMsg = pDsrc;

   return pMsg;
}
[VBScript]
Function GetEmbeddedMessage(iBp)

  Dim iMsg
  Set iMsg = CreateObject("CDO.Message")
  Dim iDsrc
  Set iDsrc = iMsg.DataSource ' get IDataSource interface

  ' open the body part object containing an embedded message
  iDsrc.OpenObject iBp, "IBodyPart"
  Set GetEmbeddedMessage = iMsg

End Function
© 2000-2001 Microsoft Corporation. All rights reserved.


Save Method

Saves data into the currently bound data source.

[Visual Basic,VBScript]
Sub Save()
[C++]
HRESULT Save();
[IDL]
HRESULT Save();

Remarks

After binding to a data source, such as another object or an item in the Web Storage System, call Save to commit changes back to the data source. This method raises the CDO_E_NOT_OPENED exception if there is currently no bound data source. If you bind an object in the Web Storage System, you must have opened it explicitly with the adModeReadWrite (3) flag set. If not, you will receive an access denied error (E_ACCESSDENIED).

Changes that must be committed using the Save method include both changes to properties within an object's Fields collection and as changes to an object's stream (where applicable). That is, calling Fields.Update on an object exposing the IDataSource interface does not commit the property changes to the underlying data source.

Invocations of the Save method are not recursive. That is, if you have a chain of open objects, calling Save on one only saves the changes back to object bound to that object. For example, if you use Message object A to open Message object B, and then you use Message object B to open Message object C, calling Save on Message A only commits the changes into Message B.

See Also

IDataSource.OpenObject, IDataSource.Open, IDataSource.SaveTo, IDataSource.SaveToObject, IDataSource.SaveToContainer


SaveTo Method

Binds to and saves data into the item with the specified URL.

[Visual Basic,VBScript]
Sub SaveTo(
  ByVal SourceURL as String,
  [ByVal ActiveConnection as Object],
  [ByVal Mode as ConnectModeEnum],
  [ByVal CreateOptions as RecordCreateOptionsEnum],
  [ByVal Options as RecordOpenOptionsEnum],
  [ByVal UserName as String],
  [ByVal Password as String]
)
[C++]
HRESULT SaveTo(
  BSTR SourceURL,
  IDispatch* ActiveConnection = 0,
  ConnectModeEnum Mode,
  RecordCreateOptionsEnum CreateOptions,
  RecordOpenOptionsEnum Options,
  BSTR UserName,
  BSTR Password
);
[IDL]
HRESULT SaveTo(
  [in] BSTR SourceURL,
  [in, defaultvalue(0)] IDispatch* ActiveConnection,
  [in, optional] ConnectModeEnum Mode,
  [in, optional] RecordCreateOptionsEnum CreateOptions,
  [in, optional] RecordOpenOptionsEnum Options,
  [in, optional] BSTR UserName,
  [in, optional] BSTR Password
);
SourceURL
The URL specifying where to save.
ActiveConnection (optional)
A reference to an existing ADO Connection object to use when saving. A new Connection (session) object is implicitly created if none is specified.
Mode (optional)
ADO defined access mode for the object. This value is always ORed with adModeReadWrite. That is, at least read-write access is required to save the item.
CreateOptions (optional)
Creation options for the new item. The values adFailIfNotExists and adOpenIfExists should not be used. If used, an E_INVALIDARG exception is raised.
Options (optional)
This specifies options flag(s) opening the source. Your setting is always ORed with adOpenSource.
Username (optional)
Used to pass a user name if needed for authentication.
Password (optional)
Used to pass a password if needed for authentication.

Remarks

The specified URL must identify a valid URL namespace that the OLE DB 2.5 root binder can resolve to a registered provider binder. Once resolved, the URL must conform to that provider binder's URL semantics.

The enumerated values and their semantic definitions are defined as part of the ADODB type library and documentation. Consult the ActiveX Data Objects (ADO) 2.5 documentation for a list of valid enumeration values and their intended purposes. Use of various enumerated values and their intended meanings are specific to a particular OLE DB 2.5 provider.

Restrictions on what types of data can be saved into a particular resource and how that data is handled by an implementation of the IDataSource interface is not part of this definition. Consult the appropriate COM class reference for further information.

Example

[Visual Basic]
' Reference to Microsoft CDO for Exchange 2000 Library
' Reference to Microsoft ActiveX Data Objects 2.5 Library

Function CreateAndSaveMessageTo(Url1 As String) As CDO.message

    Dim iDsrc As CDO.IDataSource
    Dim Conn As New ADODB.Connection
    Conn.Provider = "ExOLEDB.DataSource"
    Conn.Open Url1

    Dim iMsg As New CDO.message

    With iMsg
        .To       = "someone@microsoft.com"
        .From     = "another@microsoft.com"
        .Subject  = "Here is the subject"
        .TextBody = "Here is the text of the message"
    End With

    Set iDsrc = iMsg

    iDsrc.SaveTo Url1 & "/mymessage.eml", _
                Conn, _
                adModeReadWrite

    Set CreateAndSaveMessageTo = iMsg

End Function
[C++,IDL]
/*
 You must have the following paths in your
 INCLUDE path.
 %CommonProgramFiles%\system\ado
 %CommonProgramFiles%\microsoft shared\cdo

*/
#ifndef _CORE_EXAMPLE_HEADERS_INCLUDED
#define _CORE_EXAMPLE_HEADERS_INCLUDED
#import <msado15.dll> no_namespace
#import <cdoex.dll> no_namespace
#include <iostream.h>
#define BUFLEN   40
#endif

void SaveMessageToFolder1(IMessagePtr pMsg, bstr_t url) {

   _ConnectionPtr pConn(__uuidof(Connection));

   if(pMsg == NULL)
      throw _com_error(E_INVALIDARG);
   // for passing optional variants, we may need this
   _variant_t varOpt(DISP_E_PARAMNOTFOUND,VT_ERROR);
   IDataSourcePtr pDsrc = pMsg;

   pConn->Provider = "ExOLEDB.DataSource";
   try {
      pConn->Open(url,bstr_t(),bstr_t(),-1);
   }
   catch(_com_error e) {
      throw e;
   }
   GUID g;
   if(FAILED(CoCreateGuid(&g))) {
      cerr << "Error creating GUID" << endl;
      throw _com_error(E_FAIL);
   }
   wchar_t buf[BUFLEN];
   memset((void*)(wchar_t*)buf,0,BUFLEN);
   if( StringFromGUID2(g,(wchar_t*)buf,BUFLEN) == 0 ) {
      cerr << "Error getting string from GUID?" << endl;
      throw _com_error(E_UNEXPECTED);
   }

   try {
      pDsrc->SaveTo(
            url + bstr_t(buf) + bstr_t(".eml"),
            variant_t((IDispatch*)pConn,true), //Connection from Folder bind above
            adModeReadWrite,
            adCreateNonCollection,
            (RecordOpenOptionsEnum) NULL,
            bstr_t(),
            bstr_t()
            );
   }
   catch(_com_error e) {
      cerr << "Error saving message to folder!" << endl;
      throw e;
   }
}
[VBScript]
<job id="idatasource_saveto">
<reference object="adodb.record"/>
<reference object="cdo.message"/>
<script language="vbscript">

    Dim iDsrc
    Dim iMsg
    Dim Conn
    Dim InfoNT
    Dim Info
    Dim sFolderUrl

    Set Info   = CreateObject("ADSystemInfo")
    Set InfoNT = CreateObject("WinNTSystemInfo")
    Set Conn   = CreateObject("ADODB.Connection")
    Set iMsg   = CreateObject("CDO.Message")

    sFolderUrl = "http://" & InfoNt.ComputerName & "." & Info.DomainDNSName &  _
           "/public/test_folder/"

    Conn.Provider = "ExOLEDB.DataSource"
    Conn.Open sFolderUrl

    ' ...

    With iMsg
        .To   = "someone@microsoft.com"
        .From = "another@microsoft.com"
        .Subject = "Here is the subject"
        .TextBody = "Here is the text of the message"
    End With

    Set iDsrc = iMsg.DataSource
    iDsrc.SaveTo sFolderUrl & "/item10.eml", Conn
    Wscript.Echo "Saved To and bound to item at URL: " & iDsrc.SourceURL

    iMsg.TextBody = iMsg.TextBody & vbCrLf & "And this is another line."
    iDsrc.Save

</script>
</job>
© 2000-2001 Microsoft Corporation. All rights reserved.


SaveToContainer Method

Binds to and saves data into a new item in the folder/container specified by URL. The item name is a generated globally unique identifier (GUID).

[Visual Basic,VBScript]
Sub SaveToContainer(
  ByVal ContainerURL as String,
  [ByVal ActiveConnection as Object],
  [ByVal Mode as ConnectModeEnum],
  [ByVal CreateOptions as RecordCreateOptionsEnum],
  [ByVal Options as RecordOpenOptionsEnum],
  [ByVal UserName as String],
  [ByVal Password as String]
)
[C++]
HRESULT SaveToContainer(
  BSTR ContainerURL,
  IDispatch* ActiveConnection = 0,
  ConnectModeEnum Mode,
  RecordCreateOptionsEnum CreateOptions,
  RecordOpenOptionsEnum Options,
  BSTR UserName,
  BSTR Password
);
[IDL]
HRESULT SaveToContainer(
  [in] BSTR ContainerURL,
  [in, defaultvalue(0)] IDispatch* ActiveConnection,
  [in, optional] ConnectModeEnum Mode,
  [in, optional] RecordCreateOptionsEnum CreateOptions,
  [in, optional] RecordOpenOptionsEnum Options,
  [in, optional] BSTR UserName,
  [in, optional] BSTR Password
);
ContainerURL
The URL of the folder/collection resource into which the item is to be saved.
ActiveConnection (optional)
Specifies the optional connection to use when saving. This is an IDispatch interface to an ADO Connection object. A new Connection (session) object is implicitly created if none is specified.
Mode (optional)
Access mode. This value is always ORed with adModeReadWrite. That is, at least read-write access is required to save the item to the container/folder.
CreateOptions (optional)
Set of flags to specify creation options. The values adFailIfNotExists and adOpenIfExists should not be used. If used, an E_INVALIDARG exception is raised.
Options (optional)
This specifies options flag(s) used when opening the source. Your setting is always ORed with adOpenSource.
UserName (optional)
Not Supported - Reserved for future use. Used to pass a user name for authentication.
Password (optional)
Not Supported - Reserved for future use. Used to pass a password for authentication.

Remarks

The specified URL must identify a valid URL namespace that the OLE DB 2.5 root binder can resolve to a registered provider binder. Once resolved, the URL must conform to that provider binder's URL semantics.

The enumerated values and their semantic definitions are defined as part of the ADO type library and documentation. Consult the ActiveX Data Objects (ADO) 2.5 documentation for a list of valid enumeration values and their intended purposes. Use of various enumerated values and their intended meanings are specific to a particular OLE DB 2.5 provider.

Restrictions on what types of data can be saved into a particular resource and how that data is handled by an implementation of the IDataSource interface is not part of this definition. Consult the appropriate COM class reference for further information.

The SaveToContainer method differs from SaveTo in that the name for the resource is automatically generated for you in the container (collection) specified by URL. The name generated by this method is not defined here and is implementation specific.

After successful completion of this method, you can retrieve the full URL to the new object to which you are currently bound by examining the IDataSource.SourceURL property.

Example

[Visual Basic]
' Reference to Microsoft CDO for Exchange 2000 Library
' Reference to Microsoft ActiveX Data Objects 2.5 Library

Sub SaveEmbeddedPartsToFolder(iMsg As CDO.message, Url As String)

    Dim iMsgB As New CDO.message
    Dim iDsrcB As CDO.IDataSource
    Dim iFldr As New Folder
    Dim iDsrcFldr As CDO.IDataSource
    Dim Conn As New ADODB.Connection
    Dim iBp As IBodyPart
    Dim iBps As IBodyParts
    Dim ContType As String

    Conn.Provider = "ExOLEDB.DataSource"
    Conn.Open Url

    Set iDsrcFldr = iFldr
    iDsrcFldr.Open Url, Conn

    Set iDsrcB = iMsgB

    Set iBp = iMsg
    Set iBps = iBp.BodyParts

    For Each iBp In iBps
        ContType = iBp.ContentMediaType
        If ContType = "message/rfc822" Then

            iDsrcB.OpenObject iBp, "IBodyPart"
            iDsrcB.SaveToContainer Url, Conn, adModeReadWrite, adCreateOverwrite
            Debug.Print "Saved message has URL " & iDsrcB.SourceURL

        ElseIf ContType = "application/octet-stream" Or _
                    ContType = "application/x-msdownload" Then

            Dim iItem As New Item
            Dim Flds As ADODB.Fields
            Dim Fld As ADODB.Field
            Dim Stm1 As Stream
            Dim Stm2 As Stream

            Set Stm1 = iItem.GetStream

            ' Get Decoded BodyPart stream
            Set Stm2 = iBp.GetDecodedContentStream
            ' Copy bodypart stream to resource stream
            Stm2.CopyTo Stm1

            ' Commit
            Stm1.Flush
            Stm1.Close
            iItem.DataSource.SaveToContainer Url, Conn, adModeReadWrite

        End If
    Next iBp
End Sub
' Reference to Microsoft CDO for Exchange 2000 Library
' Reference to Microsoft ActiveX Data Objects 2.5 Library

Function CreateAndSaveMessageToContainer(Url1 As String) As CDO.message

    Dim iDsrc As CDO.IDataSource
    Dim Conn As New ADODB.Connection
    Conn.Provider = "ExOLEDB.DataSource"
    Conn.Open Url1

    Dim iMsg As New CDO.message

    With iMsg
        .To = "someone@microsoft.com"
        .From = "another@microsoft.com"
        .Subject = "Here is the subject"
        .TextBody = "Here is the text of the message"
    End With

    Set iDsrc = iMsg

    iDsrc.SaveToContainer Url1, _
                Conn, _
                adModeReadWrite

    Set CreateAndSaveMessageToContainer = iMsg

End Function
[C++,IDL]
/*
 You must have the following paths in your
 INCLUDE path.
 %CommonProgramFiles%\system\ado
 %CommonProgramFiles%\microsoft shared\cdo

*/
#ifndef _CORE_EXAMPLE_HEADERS_INCLUDED
#define _CORE_EXAMPLE_HEADERS_INCLUDED
#import <msado15.dll> no_namespace
#import <cdoex.dll> no_namespace
#include <iostream.h>
#endif

void SaveMessageToFolder2(IMessagePtr pMsg, bstr_t url) {

   _ConnectionPtr pConn(__uuidof(Connection));

   if(pMsg == NULL)
      throw _com_error(E_INVALIDARG);
   // for passing optional variants, we may need this
   _variant_t varOpt(DISP_E_PARAMNOTFOUND,VT_ERROR);
   IDataSourcePtr pDsrc = pMsg;

   pConn->Provider = "ExOLEDB.DataSource";
   try {
      pConn->Open(url,bstr_t(),bstr_t(),-1);
   }
   catch(_com_error e) {
      throw e;
   }

   try {
      pDsrc->SaveToContainer(
            url,
            variant_t((IDispatch*)pConn,true), //Connection from Folder bind above
            adModeReadWrite,
            adCreateNonCollection,
            (RecordOpenOptionsEnum) NULL,
            bstr_t(),
            bstr_t()
            );
   }
   catch(_com_error e) {
      cerr << "Error saving message to folder!" << endl;
      throw e;
   }
}
[VBScript]
<job id="idatasource_savetocontainer">
<reference object="adodb.record"/>
<reference object="cdo.message"/>
<script language="vbscript">

    Dim iDsrc
    Dim iMsg
    Dim Conn
    Dim InfoNT
    Dim Info
    Dim sFolderUrl

    Set Info   = CreateObject("ADSystemInfo")
    Set InfoNT = CreateObject("WinNTSystemInfo")
    Set Conn   = CreateObject("ADODB.Connection")
    Set iMsg   = CreateObject("CDO.Message")

    sFolderUrl = "http://" & InfoNt.ComputerName & "." & Info.DomainDNSName &  _
           "/public/test_folder/"

    Conn.Provider = "ExOLEDB.DataSource"
    Conn.Open sFolderUrl

    ' ...

    With iMsg
        .To   = "someone@microsoft.com"
        .From = "another@microsoft.com"
        .Subject = "Here is the subject"
        .TextBody = "Here is the text of the message"
    End With

    Set iDsrc = iMsg.DataSource
    iDsrc.SaveToContainer sFolderUrl, Conn
    Wscript.Echo "Saved To and bound to item at URL: " & iDsrc.SourceURL

    iMsg.TextBody = iMsg.TextBody & vbCrLf & "And this is another line."
    iDsrc.Save

</script>
</job>
© 2000-2001 Microsoft Corporation. All rights reserved.


SaveToObject Method

Binds to and saves data into the specified object.

[Visual Basic,VBScript]
Sub SaveToObject(Source as Object, InterfaceName as String)
[C++]
HRESULT SaveToObject(IUnknown* Source , BSTR InterfaceName);
[IDL]
HRESULT SaveToObject(IUnknown* Source , BSTR InterfaceName);
Source
A reference to the object in which to save.
InterfaceName
A string indicating the type of interface passed in the first argument.

Remarks

Implementations of this method are intended to allow you to easily save data into another object at run time, rather that from a particular store or database.

A sample use for SaveToObject is embedding messages into other messages. To embed a message, call IDataSource.SaveToObject passing the IBodyPart interface on a BodyPart object that is to contain the embedded message. If you subsequently wish to save changes you make to the message data into the embedded location, call IDataSource.Save, and the modified message contents are saved back to the bound BodyPart object.

Note Circular binding is not supported. You cannot use SaveToObject to bind the same object, such as:

Set iDsrc = iSomeInterface
iDsrc.SaveToObject iSomeInterface, "ISomeInterface"

If circular binding is attempted, the CDO_E_SELF_BINDING exception is raised.

After a successful binding, the IDataSource.Source is the object reference passed to the method. Avoid passing interfaces that are not OLE Automation compatible, such as Istream, if languages such as Visual Basic, Microsoft J++, and VBScript will attempt to access the bound source object through the Source property. If you pass interfaces that are not OLE Automation compatible, the object reference returned by the Source property will be unusable by these languages.

If the string passed as the interface type name (the InterfaceName parameter) is not recognized, the method must raise an exception.

Example

[Visual Basic]
Sub EmbedMessageIntoBodyPart(iBp As CDO.IBodyPart, iMsg As CDO.message)

  Dim iDsrc As CDO.IDataSource
  Set iDsrc = iMsg ' get IDataSource interface

  ' Save the message to the BodyPart object.
  ' This embeds the message in the MIME
  ' hierarchy with content-type="message/rfc822"

  iDsrc.SaveToObject iBp, "IBodyPart"

End Sub
[C++,IDL]
/*
 You must have the following paths in your
 INCLUDE path.
 %CommonProgramFiles%\system\ado
 %CommonProgramFiles%\microsoft shared\cdo

*/
#ifndef _CORE_EXAMPLE_HEADERS_INCLUDED
#define _CORE_EXAMPLE_HEADERS_INCLUDED
#import <msado15.dll> no_namespace
#import <cdoex.dll> no_namespace
#include <iostream.h>
#endif

void EmbedMessage(IBodyPartPtr pBp, IMessagePtr pMsg) {

  if(pBp == NULL || pMsg == NULL)
    throw _com_error(E_POINTER);

  IDataSourcePtr pDsrc;
  try {
     pDsrc = pMsg;
     pDsrc->SaveToObject(pBp,_bstr_t("IBodyPart"));
  }
  catch(_com_error e) {
   cerr << "Error embedding message!" << endl;
   throw e;
  }
}
[VBScript]
Sub EmbedMessageIntoBodyPart(iBp, iMsg)

  Dim iDsrc
  Set iDsrc = iMsg.DataSource ' get IDataSource interface

  ' Save the message to the BodyPart object.
  ' This embeds the message in the MIME
  ' hierarchy with content-type="message/rfc822"

  iDsrc.SaveToObject iBp, "IBodyPart"

End Sub
© 2000-2001 Microsoft Corporation. All rights reserved.


Source Property

The reference to the currently bound object.

[Visual Basic,VBScript]
Property Source as Object
Read-only
[C++]
HRESULT get_Source(IUnknown** pVal):
[IDL]
HRESULT [propget] Source([out,retval] IUnknown** pVal);

Remarks

There is a distinction between being bound to an object, and being bound to a item in a store such as Active Directory or the Web Storage System. This property returns the reference to a currently bound object. For example, if you previously bound a BodyPart object, the Source property would return the IUnknown interface on that object. However, if you are directly bound to an item in a store such as Active Directory or a Web Storage System, the Source property returns nothing. You can check whether there is a currently bound object using the IDataSource.SourceClass property. If this property returns the empty string, there is not a currently bound object.

Interfaces exposed on the bound object may not be OLE Automation compatible, and the bound object may not expose the IDispatch interface. If you are developing an application using a mix of languages such as C++, Visual Basic and script, check the IDataSource.SourceClass property before attempting to use the Source property. You must make sure the bound object supports the necessary interfaces for the particular language. For example, an implementation of the IDataSource interface may support binding to an object exposing the IStream interface. Visual Basic applications cannot use this interface. Most likely, the object exposing IStream also does not expose the IDispatch interface, ruling out use by scripting languages altogether.

[C++]

This property returns the IUnknown interface on the currently bound object. You can check the IDataSource.SourceClass to identify the name of the interface used to bind the object and may assume that this interface is supported. However, you must call QueryInterface to navigate to this interface on the object and you cannot assume that the returned reference can be statically "cast" to the interface type used to originally bind the object. This is especially important if the object on which you are invoking IDataSource methods resides in a separate COM comapartment.


SourceClass Property

The name of the interface used to bind the currently bound object.

[Visual Basic,VBScript]
Property SourceClass as String
Read-only
[C++]
HRESULT get_SourceClass(BSTR* pVal);
[IDL]
HRESULT [propget] SourceClass([out,retval] BSTR* pVal);

Remarks

The SourceClass property specifies the name of the interface used to bind the currently bound COM object. For example, if you bound and opened a BodyPart object using the IDataSource.OpenObject method, the SourceClass property is "IBodyPart" and the IDataSource.Source property is the IUnknown interface on that object. If there is no currently bound COM object, the SourceClass property returns an empty string. This does not mean that the object is not bound; the object may still be bound to an item in Active Directory or the Web Storage System.

If both the SourceURL and the SourceClass properties return an empty string, then the implementing object is not currently bound.

See Also

IDataSource.SourceURL

IDataSource.Source

IDataSource.SaveToObject

IDataSource.OpenObject

© 2000-2001 Microsoft Corporation. All rights reserved.


SourceURL Property

The URL of the currently bound item within Active Directory or the Web Storage System.

[Visual Basic,VBScript]
Property SourceURL as String
Read-only
[C++]
HRESULT get_SourceURL(BSTR* pVal);
[IDL]
HRESULT [propget] SourceURL([out,retval] BSTR* pVal);

Remarks

The SourceURL property specifies the URL of the currently bound item located in Active Directory or the Web Storage System. For example, if you bound and opened an item in the Web Storage System using the IDataSource.Open method, the SourceURL is a URL to that item. If there is no currently bound item, the SourceURL property returns an empty string. This does not mean that the object is not bound; the object may still be bound to a COM object.

If both the SourceURL and the SourceClass properties return an empty string, then the implementing object is not bound.

See Also

IDataSource.SourceClass

IDataSource.Open

IDataSource.SaveTo

IDataSource.SaveToContainer

© 2000-2001 Microsoft Corporation. All rights reserved.


IDataSource2 Interface

The IDataSource2 interface is supported by the CDO Exchange Management (CDOEXM) classes for opening, managing, and deleting Exchange related Active Directory objects.

IID
25150F48-5734-11D2-A593-00C04F990D8A
Extends
IDispatch

Member Summary

IDataSource2 supports one method.

Methods

Name | Description
Delete | Deletes an Active Directory object and performs Exchange related cleanup.

IDataSource Support

The IDataSource2 interface inherits the IDataSource Interface. The following table lists the restrictions for IDataSource properties and methods.

Properties

Name | Description
ActiveConnection | Not applicable to CDOEXM uses.
IsDirty | Not Supported.
Source | Supported. This returns an IUnknown from which you can obtain an IADS interface.
SourceClass | Supported.
SourceURL | Supported.

Methods

Name | Description
Open | Supported. ADO options ignored.
OpenObject | Supported.
Save | Supported.
SaveTo | Supported. ADO options ignored.
SaveToContainer | Supported. ADO options ignored.
SaveToObject | Not Supported.

Remarks

Flags for the Open, SaveTo, and SaveToContainer are not supported by CDOEXM.


Delete Method

Deletes the currently bound object or resource.

[Visual Basic,VBScript]
Sub Delete()
[C++]
HRESULT Delete();
[IDL]
HRESULT Delete();

Remarks

Delete will delete the currently bound Active Directory object. While you could use other means to delete Exchange related Active Directory objects, the IDataSource2 Delete method also performs numerous Exchange related checks and cleanup procedures necessary for proper store maintenance.


IDistributionList Interface

Provides control of the display of distribution lists.

IID
25150F3F-5734-11D2-A593-00C04F990D8A
Extends
IDispatch

Member Summary

Properties

Name | Type | Description
HideDLMembership | [Visual Basic,VBScript] Boolean [C++,IDL] VARIANT_BOOL | Hide the membership list on a distribution list.


HideDLMembership Property

Hide the membership list on a distribution list from senders.

[Visual Basic,VBScript]
Public Property HideDLMembership as Boolean
[C++]
HRESULT get_HideDLMembership (VARIANT_BOOL* pHideDLMembership);
HRESULT put_HideDLMembership (VARIANT_BOOL pHideDLMembership);
[IDL]
HRESULT [propget] HideDLMembership ([out,retval] VARIANT_BOOL* pHideDLMembership);
HRESULT [propput] HideDLMembership ([in] VARIANT_BOOL pHideDLMembership);

Remarks

This interface is aggregated into ADSI for recipient management. See Managing Mail Recipients for more information.


IDropDirectory Interface

Defines an abstract method used to access a collection of messages that reside either in the SMTP default drop directory or in some other specified file system directory.

Note Because IDropDirectory is only used for accessing messages on a file system, it is not useful in CDO for Exchange where messages are saved in the Microsoft® Web Storage System.

IID
CD000024-8B95-11D1-82DB-00C04FB1625D
Extends
IDispatch

Member Summary

Method

Name | Description
GetMessages | Returns a collection containing the messages in the specified directory.

Remarks

COM objects expose the IDropDirectory interface to provide access to a collection of messages stored on the file system. The GetMessages method returns a collection object exposing the IMessages interface. Each object in the collection is an instance of the Message COM class and contains the complete message stored in the file. If no file system path is specified, the SMTP service default drop directory is used. The default drop directory is where newly arrived messages are stored for local users.

Microsoft® Windows® 2000 does not provide direct mailbox support. Instead, incoming mail messages are delivered to a physical disk directory called a drop directory and placed in files with the .eml extension. Outgoing messages are placed in another disk directory called a pickup directory. When you install and configure Windows 2000 Server, the SMTP service determines path and file names for the drop and pickup directories. These directories are initialized and maintained by the service, and are the default locations for inbound and outgoing messages.

Example

[Visual Basic]
Dim iDropDir as New CDO.DropDirectory
Dim iMsgs as CDO.IMessages
Set iMsgs = iDropDir.GetMessages("c:\Inetput\mailroot\Drop")
' you now have the collection of messages
' in the SMTP drop directory
...
Set iMsgs = iDropDir.GetMessages("c:\mymessages")
' you now have the collection of messages
' located in the directory c:\mymessages
[C++,IDL]
#import "c:\program files\common files\system\ado\msado15.dll" no_namespace raw_interfaces_only
#import "c:\winnt\system32\cdosys.dll" no_namespace raw_interfaces_only
main() {
   CoInitialize(NULL);

   IDropDirectory* pDropDir = NULL;
   IMessages*      pMsgs    = NULL;
   CoCreateInstance(
      __uuidof(DropDirectory),
      NULL,
      CLSCTX_INPROC_SERVER,
      __uuidof(IDropDirectory),
      (void**)pDropDir
   );

    // get collection from SMTP drop directory
    pDropDir->GetMessages(L"c:\\Inetput\\mailroot\\Drop",&pMsgs);
    pMsgs->Release();
    // get collection from specific directory
    pDropDir->GetMessages(L"c:\\mymessages",&pMsgs);
    pMsgs->Release();
    pDropDir->Release();
    CoUninitialize();
}
[VBScript]
Dim iDropDir
Set iDropDir = CreateObject("CDO.Configuration")
Dim iMsgs
Set iMsgs = iDropDir.GetMessages("c:\Inetpub\mailroot\Drop")
' you now have the collection of messages
' in the SMTP drop directory
...
Set iMsgs = iDropDir.GetMessages("c:\mymessages")
' you now have the collection of messages
' located in the directory c:\mymessages
© 2000-2001 Microsoft Corporation. All rights reserved.


GetMessages Method

Returns a collection containing the messages in the specified directory.

[Visual Basic]
Function GetMessages([ByVal DirName as String]) as IMessages
[C++]
HRESULT GetMessages(BSTR DirName, IMessages** pVal);
[IDL]
HRESULT GetMessages([in, optional] BSTR DirName, [out,retval] IMessages** pVal);
DirName
The path to a directory that contains the messages. This parameter is optional, and if the empty string "" is specified, the currently defined SMTP drop directory is assumed.

Remarks

The collection returned by GetMessages contains Message objects derived from the files present in the directory at the time the method was invoked. The collection is not automatically updated when new messages arrive in the directory. To refresh the collection, call GetMessages again to retrieve a new collection.

Example

[Visual Basic]
Dim iDropDir as New CDO.DropDirectory
Dim iMsgs as CDO.IMessages
Set iMsgs = iDropDir.GetMessages("c:\Inetput\mailroot\Drop")
' you now have the collection of messages
' in the SMTP drop directory
...
Set iMsgs = iDropDir.GetMessages("c:\mymessages")
' you now have the collection of messages
' located in the directory c:\mymessages
[C++,IDL]
#import "c:\program files\common files\system\ado\msado15.dll" no_namespace raw_interfaces_only
#import <cdosys.dll> no_namespace raw_interfaces_only
main() {
  CoInitialize(NULL);

  IDropDirectory* pDropDir = NULL;
  IMessages*      pMsgs    = NULL;
  CoCreateInstance(
    __uuidof(DropDirectory),
    NULL,
    CLSCTX_INPROC_SERVER,
    __uuidof(IDropDirectory),
    (void**)pDropDir);
    // get collection from SMTP drop directory
    pDropDir->GetMessages(L"c:\\Inetput\\mailroot\\Drop",&pMsgs);
   // ...
    pMsgs->Release();
   // get collection from specific directory
    pDropDir->GetMessages(L"c:\\mymessages",&pMsgs);
   //  ...
   pMsgs->Release();
   pDropDir->Release();
  CoUninitialize();
  return 1;
}
[VBScript]
Dim iDropDir
Set iDropDir = CreateObject("CDO.Configuration")
Dim iMsgs
Set iMsgs = iDropDir.GetMessages("c:\Inetpub\mailroot\Drop")
' you now have the collection of messages
' in the SMTP drop directory
...
Set iMsgs = iDropDir.GetMessages("c:\mymessages")
' you now have the collection of messages
' located in the directory c:\mymessages
© 2000-2001 Microsoft Corporation. All rights reserved.


IException Interface

Provides access to properties and fields for creating or processing an exception to a recurring meeting.

IID
CD000124-8B95-11D1-82DB-00C04FB1625D
Extends
IDispatch

Member Summary

Properties

Name | Type | Description
EndTime | [Visual Basic, VBScript]Date [C++,IDL] DATE | Contains the end time of an appointment instance being added, or the new end time of an appointment instance being modified.
Fields (Read-only) | [Visual Basic, VBScript] ADODB.Fields [C++,IDL] Fields* | Returns a Fields collection for the object. Used to change field values for an appointment instance being modified.
RecurrenceID | [Visual Basic, VBScript] Date [C++,IDL] DATE | Returns the starting date and time of an appointment instance being deleted or modified.
RecurrenceIDRange | [Visual Basic, VBScript] String [C++,IDL] BSTR | Modifies the meaning of the RecurrenceID property to refer to multiple instances of a recurring meeting.
StartTime | [Visual Basic, VBScript] Date [C++,IDL] DATE | Contains the start time of an appointment instance being added, or the new start time of an appointment instance being modified.
Type (Read-only) | [Visual Basic, VBScript] String [C++,IDL] BSTR | Specifies whether to add, delete, or modify an appointment instance.


EndTime Property

Contains the end time of an appointment instance being added, or the new end time of an appointment instance being modified.

[Visual Basic,VBScript]
Property EndTime as Date
[C++]
HRESULT get_EndTime(DATE* pVal);
HRESULT put_EndTime(Date Val);
[IDL]
HRESULT [propget] EndTime([out,retval] DATE* pVal);
HRESULT [propput] EndTime([in] DATE Val);


Fields Property

Returns a Fields collection for the object. The Fields collection is used to change the value of one or more fields of an appointment instance being modified.

[Visual Basic,VBScript]
Property Fields as ADODB.Fields
read-only
[C++]
HRESULT get_Fields(Fields** pVal);
[IDL]
HRESULT [propget] Fields([out,retval] Fields** pVal);

Remarks

The ADO Fields object is a collection of ADO Field objects that pertain to this object. Each Field object holds a name/value pair defining some header field for the body part. The name is always a string, and the value is a VARIANT. The subtype of the VARIANT depends on the schema definition for the name. See the appropriate schema fields section of the reference for a list of valid fields to use along with a list of the VARIANT subtypes for each field.

Note When you use the ADO Fields.Update method, field values are updated only in memory. You must call IDataSource.Save to save the changes to the Web Storage System. To get the IDataSource interface, use the GetInterface method on the CDO object.

The fields that resize in this collection depend upon the specific implementation. Consult the appropriate COM class for details about available fields.


RecurrenceID Property

Returns the starting date and time of an appointment instance being deleted or modified.

[Visual Basic,VBScript]
Property RecurrenceID as Date
[C++]
HRESULT get_RecurrenceID(DATE* pVal);
HRESULT put_RecurrenceID(DATE Val);
[IDL]
HRESULT [propget] RecurrenceID([out,retval] DATE* pVal);
HRESULT [propput] RecurrenceID([in] DATE Val);

Remarks

This property is also available as the schema field recurrenceid.


RecurrenceIDRange Property

Modifies the meaning of the RecurrenceID property to refer to multiple instances of a recurring meeting.

[Visual Basic,VBScript]
Property RecurrenceIDRange as String
[C++]
HRESULT get_RecurrenceIDRange(BSTR* pVal);
HRESULT put_RecurrenceIDRange(BSTR Val);
[IDL]
HRESULT [propget] RecurrenceIDRange([out,retval] BSTR* pVal);
HRESULT [propput] RecurrenceIDRange([in] BSTR Val);

Remarks

The value "ThisAndFuture" refers to the instance specified by the RecurrenceID property, and to all later instances of the recurring appointment. The value "ThisAndPrior" refers to the instance specified by the RecurrenceID property, and to all earlier instances of the recurring appointment. The default value is "None," which means the RecurrenceID property refers to a single instance.

Use constant values from CdoRecurrenceIdRangeValues.

Constant | Value
cdoNone | None
cdoThisAndFuture | ThisAndFuture
cdoThisAndPrior | ThisAndPrior

This property is also available as the schema field recurrenceidrange.


StartTime Property

Contains the start time of an appointment instance being added or the new start time of an appointment instance being modified.

[Visual Basic,VBScript]
Property StartTime as Date
[C++]
HRESULT get_StartTime(DATE* pVal);
HRESULT put_StartTime(Date Val);
[IDL]
HRESULT [propget] StartTime([out,retval] DATE* pVal);
HRESULT [propput] StartTime([in] DATE Val);


Type Property

Specifies the action to take on an appointment instance.

[Visual Basic,VBScript]
Property Type as String
read-only
[C++]
HRESULT get_Type(BSTR* pVal);
IDL]
HRESULT [propget] Type([out,retval] BSTR* pVal);

Remarks

The valid values are ADD, DELETE, and MODIFY.


IExceptions Interface

The IExceptions interface defines properties and methods that enable access to a collection of Exception objects.

When you create a recurring appointment, you can use the IExceptions interface to add multiple exceptions to a master recurring appointment. When you process an existing recurring appointment or meeting request, you need to use the IExceptions interface to get access to each exception, contained in an Exception object.

IID
CD00012D-8B95-11D1-82DB-00C04FB1625D
Extends
IDispatch

Member Summary

Properties

Name | Type | Description
Count (Read-only) | [Visual Basic, VBScript] Long [C++,IDL] long | Returns the number of Exception objects in the collection.
Item (Read-only) | [Visual Basic, VBScript] IException [C++,IDL] IException* | Returns a reference to the object at a given index in the collection.
_NewEnum (Read-only) | [Visual Basic,VBScript] (Used in For Each In) [C++,IDL] IUnknown* | Returns an IEnumVariant interface on an enumeration object. (This property is hidden from Microsoft® Visual Basic® and is used in For EachIin constructs.)

Methods

Name | Description
Add | Adds an Exception object to the collection.
Delete | Removes the specified Exception object from the collection.

Remarks

The collection index always ranges from 1 to the value returned by the Count property.


Count Property

Returns the number of Exception objects in the collection.

[Visual Basic, VBScript]
Property Count as Long
read-only
[C++]
HRESULT get_Count(long* pVal);
[IDL]
HRESULT [propget] Count([out,retval] long* pVal);


Item Property

Returns the Exception object specified by the index.

[Visual Basic, VBScript]
Property Item(ByVal Index as Long) as IException
read-only
[C++]
HRESULT get_Item( long Index, IException** pVal);
[IDL]
HRESULT [propget] Item([in] long Index, [out,retval] IBodyPart** pVal);

Remarks

The collection index always ranges from 1 to the value returned by the Count property.

Item is the default member on the interface.


_NewEnum Property

Returns an IEnumVariant interface on an enumeration object for the collection. This property is hidden from Microsoft® Visual Basic® and Microsoft® Visual Basic® Scripting Edition (VBScript).

[Visual Basic, VBScript]

Used automatically in For Each In constructs.

[C++]
HRESULT get__NewEnum(IUnknown** pVal);
[IDL]
HRESULT [propget] _NewEnum([out,retval] IUnknown** pVal);

Remarks

This property is hidden within Visual Basic and VBScript. It is a standard property used to support enumerating collections, such as the For Each in construct in Visual Basic

Example

[Visual Basic]
Dim iEx as IException
Dim iExs as IExceptions
...
For Each iEx in iExs   ' _NewEnum used internally here
...
Next iEx
© 2000-2001 Microsoft Corporation. All rights reserved.


Add Method

Adds a new Exception object to the collection.

[Visual Basic, VBScript]
Sub Add(Type As String) As IException
[C++]
HRESULT Add(BSTR Type, IExceptions** pVal);
[IDL]
HRESULT Add(
[in] BSTR Type,
[out, retval] IExceptions** pVal);
);
Type
The type of exception being added. The valid values are Add, Delete, and Modify.

Remarks

Adding an Exception object with type "Add" adds an appointment instance to a recurring appointment. This exception object generates the iCalendar RDATE property.

Adding an Exception object with type "Delete" removes an appointment instance from a recurring appointment. This exception object generates the iCalendar EXDATE property.

Adding an Exception object with type "Modify" changes one or more properties of an appointment instance of a recurring appointment.

Example

The following example creates an Exception object to delete an instance of a recurring appointment:

[Visual Basic]
Dim objAppt as New Appointment
Dim objEXDATE as IException
...
Set objEXDATE = objAppt.Exceptions.Add("Delete")


Delete Method

Removes the specified Exception object from the collection.

[Visual Basic, VBScript]
Sub Delete(Index as Long)
[C++]
HRESULT Delete(long* Index);
[IDL]
HRESULT Delete([in] LONG Index );
Index
The ordinal index of the Exception object being removed from the collection.

Remarks

The collection index always ranges from 1 to the value returned by the Count property.


IExchangeServer Interface

This interface is for managing the overall Microsoft® Exchange 2000 Server.

IID
25150F47-5734-11D2-A593-00C04F990D8A
Extends
IDispatch

Member Summary

Properties

Name | Type | Description
DataSource (Read-Only) | IDataSource2 [C++,IDL] IDataSource2* | Returns the IDataSource2 interface on the object.
DaysBeforeLogFileRemoval | [Visual Basic,VBScript] Long [C++,IDL] Long | The number of days before log files are deleted from the server.
DirectoryServer (Read-only) | [Visual Basic,VBScript] String [C++,IDL]BSTR | The domain controller used by services on this machine.
ExchangeVersion (Read-only) | [Visual Basic,VBScript] String [C++,IDL] BSTR | The version of Exchange installed on this server.
Fields (Read-Only) | [Visual Basic] ADODB.Fields [C++,IDL] Fields* | The object's Fields collection.
MessageTrackingEnabled | [Visual Basic,VBScript] Boolean [C++,IDL] VARIANT_BOOL | Toggles message tracking for the server.
Name (Read-only) | [Visual Basic,VBScript] String [C++,IDL]BSTR | The name of the server.
ServerType | [Visual Basic,VBScript] CDOEXMServerType [C++,IDL]CDOEXMServerType | The server type for this server.
StorageGroups (Read-only) | [Visual Basic,VBScript] Variant [C++,IDL] VARIANT | A list of storage groups on this server.
SubjectLoggingEnabled | [Visual Basic,VBScript] Boolean [C++,IDL] VARIANT_BOOL | Toggles subject logging and display.

Methods

Name | Description
GetInterface | Returns the specified dual interface on the object.


DataSource Property

Returns the IDataSource2 interface on this object.

[Visual Basic]
Property DataSource as IDataSource2
read-only
[C++]
HRESULT get_DataSource(IDataSource2** pVal);
[IDL]
HRESULT [propget] DataSource([out,retval] IDataSource2** pVal);

Remarks

You can use the DataSource property to obtain the IDataSource2 interface on this object. This is equivalent to using QueryInterface in C++ or Set in Microsoft® Visual Basic®, or using the GetInterface method.


DaysBeforeLogFileRemoval Property

Gets or sets the number of days before log files are deleted from the server.

[Visual Basic,VBScript]
Property DaysBeforeLogFileRemoval as Long
[C++]
HRESULT get_DaysBeforeLogFileRemoval(long* pVal);
HRESULT put_DaysBeforeLogFileRemoval(long Val);
[IDL]
HRESULT [propget] DaysBeforeLogFileRemoval([out,retval] long* pVal);
HRESULT [propput] DaysBeforeLogFileRemoval([in] long Val);

Remarks

The default value for this property is -1 (no removal).

A new log file is created for each day of server operation. The log files are named according to the day that data is logged in them.

If DaysBeforeLogFileRemoval is set to 2, then any log files created more than two days ago will be deleted.


DirectoryServer Property

Returns the domain controller used by services on this machine.

[Visual Basic,VBScript]
Property DirectoryServer as String
read-only
[C++]
HRESULT get_DirectoryServer(BSTR* pVal);
[IDL]
HRESULT [propget] DirectoryServer([out,retval] BSTR* pVal);


ExchangeVersion Property

The version of Exchange installed on this server.

[Visual Basic,VBScript]
Property ExchangeVersion as String
read-only
[C++]
HRESULT get_ExchangeVersion(BSTR* pVal);

[IDL]
HRESULT [propget] ExchangeVersion([out,retval] BSTR* pVal);

Example

"Version 6.0 (Build 4250.8)"

© 2000-2001 Microsoft Corporation. All rights reserved.


Fields Property

The Fields collection for the object.

[Visual Basic]
Property Fields as ADODB.Fields
read-only
[C++]
HRESULT get_Fields(Fields** pVal);
[IDL]
HRESULT [propget] Fields([out,retval] Fields** pVal);

Remarks

The Fields property obtains a collection of ADO Field objects each of which contains a field relating to the Server object.

Note When you use the ADO Fields.Update method, field values are updated only in memory. You must call IDataSource.Save to save the changes to the Web Storage System. To get the IDataSource interface, use the GetInterface method on the CDO object.


MessageTrackingEnabled Property

Toggles message tracking for the server.

[Visual Basic,VBScript]
Property MessageTrackingEnabled as Boolean
[C++]
HRESULT get_MessageTrackingEnabled (VARIANT_BOOL* pVal);
HRESULT put_MessageTrackingEnabled (VARIANT_BOOL pVal);
[IDL]
HRESULT [propget] MessageTrackingEnabled ([out,retval] VARIANT_BOOL* pVal);
HRESULT [propput] MessageTrackingEnabled ([in] VARIANT_BOOL pVal);

Remarks

Message tracking is enabled when set to true.

If enabled, the subject will be viewable in the message tracking logs and in the queue viewer in Exchange System Manager. Before setting this to true, administrators should consider any privacy implications.


Name Property

Returns the name of this server.

[Visual Basic,VBScript]
Property Name as String
read-only
[C++]
HRESULT get_Name(BSTR* pVal);
[IDL]
HRESULT [propget] Name([out,retval] BSTR* pVal);


ServerType Property

Gets or sets the server type for this server.

[Visual Basic]
Property ServerType as CDOEXMServerType
[C++]
HRESULT get_ServerType(CDOEXMServerType* pVal);
HRESULT put_ServerType(CDOEXMServerTypeVal);
[IDL]
HRESULT [propget] ServerType([out,retval] CDOEXMServerType* pVal);
HRESULT [propput] ServerType([in] CDOEXMServerType Val);

Remarks

The CDOEXMServerType enumeration is provided for this property. It indicates whether the server is a front-end or back-end server. Front-end servers function as visible servers to clients such as POP, IMAP, or HTTP. Front-end servers proxy protocols to back-end servers that have the actual stores.

Note The server type is back-end by default. Changing a server to front-end cannot be undone.

See Also

CDOEXMServerType Enum

© 2000-2001 Microsoft Corporation. All rights reserved.


StorageGroups Property

Returns a list of storage groups on this server.

[Visual Basic,VBScript]
Property StorageGroups as Variant
read-only
[C++]
HRESULT get_StorageGroups (VARIANT* pVal);
[IDL]
HRESULT [propget] StorageGroups ([out,retval] VARIANT* pVal);


SubjectLoggingEnabled Property

Indicates whether subject logging and display is enabled for this server.

 [Visual Basic,VBScript]
Property SubjectLoggingEnabled as Boolean
[C++]
HRESULT get_SubjectLoggingEnabled (VARIANT_BOOL* pVal);
HRESULT put_SubjectLoggingEnabled (VARIANT_BOOL pVal);
[IDL]
HRESULT [propget] SubjectLoggingEnabled ([out,retval] VARIANT_BOOL* pVal);
HRESULT [propput] SubjectLoggingEnabled ([in] VARIANT_BOOL pVal);

Remarks

Subject Logging is enabled when set to true.


GetInterface Method

Returns the specified dual interface on the object.

[Visual Basic]
Function GetInterface(ByVal Interface as String) as Object
[C++]
HRESULT GetInterface(BSTR Interface, IDispatch** pVal);
[IDL]
HRESULT GetInterface([in] BSTR Interface, [out,retval] IDispatch** pVal);
Interface
The name of the interface to obtain.

Remarks

The GetInterface method is primarily intended as a generic interface navigation aid to scripting languages that do not support such navigation directly. Most COM classes that provide implementations of the IMessage interface expose additional dual interfaces that are accessible by scripting languages only through properties on the interface, such as BodyPart and DataSource, or through the GetInterface method. When properties do not exist on the interface to return these interfaces, the GetInterface method must be used.

The list of valid interface names to pass to GetInterface is dependent upon a specific implementation. As a general rule, the name of the desired interface should match the physical name of the interface as it appears in the type library or .idl file. Check the appropriate COM class for a list of exposed dual interfaces.

Example

The following examples demonstrate using GetInterface to return other interfaces on an ExchangeServer object.

VBScript
Dim iExchSvr
'Create an instance and get IExchangeServer (IDispatch) back
Set iExchSvr = CreateObject("CDOEXM.ExchangeServer")

'Get IDataSource2 on the ExchangeServer Object
Set iDsrc = iExchSvr.GetInterface("IDataSource2")
JScript
var iExchSvr = new ActiveXObject("CDOEXM.ExchangeServer");
var iDsrc = iExchSvr.GetInterface("IDataSource2");


IFolder Interface

The IFolder interface defines methods and properties used to access a folder in a Microsoft® Exchange 2000 Server public or private store, or a folder in a Microsoft® Web Storage System.

IID
CD000132-8B95-11D1-82DB-00C04FB1625D
Extends
IDispatch

Member Summary

Properties

Name | Type | Description
Configuration | IConfiguration IConfiguration* | The Configuration object for the folder.
ContentClass | [Visual Basic,VBScript] String [C++,IDL] BSTR | The content class of the folder.
DataSource (Read-Only) | IDataSource [C++,IDL] IDataSource* | The IDataSource interface on the object.
Description | [Visual Basic,VBScript] String [C++,IDL] BSTR | The description of the folder.
DisplayName (Read-Only) | [Visual Basic,VBScript] String [C++,IDL] BSTR | The display name of the folder.
EmailAddress (Read-Only) | [Visual Basic,VBScript] String [C++,IDL] BSTR | The e-mail address of this folder.
Fields (Read-only) | [Visual Basic,VBScript] ADODB.Fields [C++,IDL] Fields* | The ADO Fields collection for the folder. The object contains the properties associated with this folder item.
HasSubFolders (Read-only) | [Visual Basic,VBScript] Boolean [C++,IDL] VARIANT_BOOL | Indicates whether the folder contains subfolders.
ItemCount (Read-only) | [Visual Basic,VBScript] Long [C++,IDL] long | The number of nonfolder items in the folder.
UnreadItemCount (Read-only) | [Visual Basic,VBScript] Long [C++,IDL] long | The number of items in the folder not marked as read.
VisibleCount (Read-only) | [Visual Basic,VBScript] Long [C++,IDL] long | The number of visible nonfolder items in the folder. All nonfolder items that are not in the folder's associated contents table (often referred to as non-FAI messages) are visible. Items with their DAV:ishidden property set to True are reported in this count.

Methods

Name | Description
GetInterface | Returns a specified interface on this object. Acts as a QueryInterface or Set method for scripting languages.

Remarks

The CDO Folder object exposes an implementation of the IFolder interface. Folder objects provide access to information about a folder in a Microsoft Exchange private or public store, or a Web Storage System. Such information includes the number of nonfolder items in the folder, the number of unread messages, and whether the folder has subfolders.

Many of the properties exposed on the IFolder interface correspond one-to-one with properties in the IFolder.Fields collection. You can use either the interface properties or the properties in the Fields collection; both methods provide access to folder properties.

The IFolder.DataSource property returns interfaces on the object. Other interfaces may exist, such as IMailRecipient. To access these interfaces, scripting languages use the IFolder.GetInterface method. The IMailRecipient interface is present for a Folder object if the CDO for Exchange Management COM component is installed. Other languages, such as C++ and Microsoft® Visual Basic®, can use also an appropriate interface navigation method such as QueryInterface and Set.

Example

[Visual Basic]
' Reference to Microsoft ActiveX Data Objects 2.5 Library
' Reference to Microsoft CDO for Exchange 2000 Library

Function CreateFolder(Url As String, _
                       ContentClass As String, _
                       Description As String)
  Set Fldr = New CDO.Folder
  With Fldr
    .ContentClass = ContentClass
    .Description = Description
    .DataSource.SaveTo Url, , _
                       adModeReadWrite, _
                       adCreateCollection Or adCreateOverwrite

  End With
  Set CreateFolder = Fldr

End Function
[VBScript]
Function CreateFolder( Url, ContentClass, Description )
  Set Fldr = CreateObject("CDO.Folder")
  With Fldr
    .ContentClass = ContentClass
    .Description  = Description
    On Error Resume Next
    .DataSource.Open Url, , adModeReadWrite

    If Err.Number <> 0 Then
      Err.Clear
      .DataSource.SaveTo Url, , _
                        adModeReadWrite, _
                       adCreateCollection Or adCreateOverWrite
      If Err.Number <> 0 Then
       ' Handle error
      End If
    End If
  End With

  On Error Goto 0
  Set CreateFolder = Fldr

End Function
[C++]
/*
 You must have the following paths in your
 INCLUDE path.
 %CommonProgramFiles%\system\ado
 %CommonProgramFiles%\microsoft shared\cdo

*/
#ifndef _CORE_EXAMPLE_HEADERS_INCLUDED
#define _CORE_EXAMPLE_HEADERS_INCLUDED
#import <msado15.dll> no_namespace
#import <cdoex.dll> no_namespace
#include <iostream.h>
#endif

IFolderPtr CreateFolder(bstr_t url, bstr_t contentclass, bstr_t description) {

   if(url == bstr_t(""))
      throw _com_error(E_POINTER);

   _ConnectionPtr Conn(__uuidof(Connection));
   IDataSourcePtr pDsrc(__uuidof(Folder));

   Conn->Provider = "ExOLEDB.DataSource";
   try {
      Conn->Open(url,bstr_t(),bstr_t(),-1);
   }
   catch(_com_error e) {
      throw e;
   }

   IFolderPtr pFldr = pDsrc;

   pFldr->ContentClass = contentclass;
   pFldr->Description  = description;

   try {
      pDsrc->SaveTo(
         url,
         variant_t((IDispatch*)Conn,true),
         adModeReadWrite,
         (RecordCreateOptionsEnum)
            (   adCreateCollection |
               adCreateOverwrite
            ),
         adOpenSource,
         bstr_t(),
         bstr_t());
   }
   catch(_com_error e) {
      cerr << "Error saving folder to store" << endl;
      throw e;
   }
   return pFldr;
}


Configuration Property

The Configuration object for the object.

[Visual Basic,VBScript]
Property Configuration as CDO.Configuration
[C++]
HRESULT get_Configuration(IConfiguration** pVal);
HRESULT put_Configuration(IConfiguration* Val);
[IDL]
HRESULT [propget] Configuration([out,retval] IConfiguration** pVal);
HRESULT [propput] Configuration([in] IConfiguration* Val);


ContentClass Property

The folder's content class.

[Visual Basic,VBScript]
Property ContentClass as String
[C++]
HRESULT get_ContentClass(BSTR* pVal);
HRESULT put_ContentClass(BSTR Val);
[IDL]
HRESULT [propget] ContentClass([out,retval] BSTR* pVal);
HRESULT [propput] ContentClass([in] BSTR Val);

Remarks

The ContentClass property is used to indicate the intent or purpose of the folder. For example, a user's inbox has a content class of "urn:content-classes:mailfolder".

The content class is not the same as the PR_CONTAINER_CLASS MAPI property.

Example

[Visual Basic]
' Reference to Microsoft ActiveX Data Objects 2.5 Library
' Reference to Microsoft CDO for Exchange 2000 Library

Function CreateFolder(Url As String, _
                       ContentClass As String, _
                       Description As String)
  Set Fldr = New CDO.Folder
  With Fldr
    .ContentClass = ContentClass
    .Description = Description
    .DataSource.SaveTo Url, , _
                       adModeReadWrite, _
                       adCreateCollection Or adCreateOverwrite

  End With
  Set CreateFolder = Fldr

End Function
[VBScript]
Function CreateFolder( Url, ContentClass, Description )
  Set Fldr = CreateObject("CDO.Folder")
  With Fldr
    .ContentClass = ContentClass
    .Description  = Description
    On Error Resume Next
    .DataSource.Open Url, , adModeReadWrite

    If Err.Number <> 0 Then
      Err.Clear
      .DataSource.SaveTo Url, , _
                        adModeReadWrite, _
                       adCreateCollection Or adCreateOverWrite
      If Err.Number <> 0 Then
       ' Handle error
      End If
    End If
  End With

  On Error Goto 0
  Set CreateFolder = Fldr

End Function
[C++]
/*
 You must have the following paths in your
 INCLUDE path.
 %CommonProgramFiles%\system\ado
 %CommonProgramFiles%\microsoft shared\cdo

*/
#ifndef _CORE_EXAMPLE_HEADERS_INCLUDED
#define _CORE_EXAMPLE_HEADERS_INCLUDED
#import <msado15.dll> no_namespace
#import <cdoex.dll> no_namespace
#include <iostream.h>
#endif

IFolderPtr CreateFolder(bstr_t url, bstr_t contentclass, bstr_t description) {

   if(url == bstr_t(""))
      throw _com_error(E_POINTER);

   _ConnectionPtr Conn(__uuidof(Connection));
   IDataSourcePtr pDsrc(__uuidof(Folder));

   Conn->Provider = "ExOLEDB.DataSource";
   try {
      Conn->Open(url,bstr_t(),bstr_t(),-1);
   }
   catch(_com_error e) {
      throw e;
   }

   IFolderPtr pFldr = pDsrc;

   pFldr->ContentClass = contentclass;
   pFldr->Description  = description;

   try {
      pDsrc->SaveTo(
         url,
         variant_t((IDispatch*)Conn,true),
         adModeReadWrite,
         (RecordCreateOptionsEnum)
            (   adCreateCollection |
               adCreateOverwrite
            ),
         adOpenSource,
         bstr_t(),
         bstr_t());
   }
   catch(_com_error e) {
      cerr << "Error saving folder to store" << endl;
      throw e;
   }
   return pFldr;
}


DataSource Property

The IDataSource interface on the object.

[Visual Basic,VBScript]
Property DataSource as IDataSource
read-only
[C++]
HRESULT get_DataSource(IDataSource** pVal);
[IDL]
HRESULT [propget] DataSource([out,retval] IDataSource** pVal);

Remarks

This property returns the IDataSource interface on the object. Use the IDataSource interface exposed by the object to bind to items in a Microsoft Exchange public or private store, a Web Storage System, or other objects, such as ADO Record or OLE DB Row objects. When binding to Record and Row objects, the underlying store item must be a container.

Example

[Visual Basic]
' Reference to Microsoft ActiveX Data Objects 2.5 Library
' Reference to Microsoft CDO for Exchange 2000 Library

Function GetBoundFolder(Url As String) As CDO.Folder
  Set Fldr = New Folder
  Set GetBoundFolder = Fldr.DataSource.Open(Url, , _
                                            adModeReadWrite, _
                                            adFailIfNotExists)

End Function
[VBScript]
Function GetBoundFolder( Url )
  Set Fldr = CreateObject("CDO.Folder")
  Set GetBoundFolder = Fldr.DataSource.Open(Url, , _
                                            adModeReadWrite, _
                                            adFailIfNotExists)

End Function
[C++]
/*
 You must have the following paths in your
 INCLUDE path.
 %CommonProgramFiles%\system\ado
 %CommonProgramFiles%\microsoft shared\cdo

*/
#ifndef _CORE_EXAMPLE_HEADERS_INCLUDED
#define _CORE_EXAMPLE_HEADERS_INCLUDED
#import <msado15.dll> no_namespace
#import <cdoex.dll> no_namespace
#include <iostream.h>
#endif

IFolderPtr CreateFolder(bstr_t url, bstr_t contentclass, bstr_t description) {

   if(url == bstr_t(""))
      throw _com_error(E_POINTER);

   _ConnectionPtr Conn(__uuidof(Connection));
   IDataSourcePtr pDsrc(__uuidof(Folder));

   Conn->Provider = "ExOLEDB.DataSource";
   try {
      Conn->Open(url,bstr_t(),bstr_t(),-1);
   }
   catch(_com_error e) {
      throw e;
   }

   IFolderPtr pFldr = pDsrc;

   pFldr->ContentClass = contentclass;
   pFldr->Description  = description;

   try {
      pDsrc->SaveTo(
         url,
         variant_t((IDispatch*)Conn,true),
         adModeReadWrite,
         (RecordCreateOptionsEnum)
            (   adCreateCollection |
               adCreateOverwrite
            ),
         adOpenSource,
         bstr_t(),
         bstr_t());
   }
   catch(_com_error e) {
      cerr << "Error saving folder to store" << endl;
      throw e;
   }
   return pFldr;
}


Description Property

A description of the folder.

[Visual Basic,VBScript]
Property Description as String
[C++]
HRESULT get_Description(BSTR* pVal);
HRESULT put_Description(BSTR Val);
IDL]
HRESULT [propget] Description([out,retval] BSTR* pVal);
HRESULT [propput] Description([in] BSTR Val);

Remarks

This property is normally set by administrators to provide an administrative note for the folder.

Example

[Visual Basic]
' Reference to Microsoft ActiveX Data Objects 2.5 Library
' Reference to Microsoft CDO for Exchange 2000 Library

Function CreateFolder(Url As String, _
                       ContentClass As String, _
                       Description As String)
  Set Fldr = New CDO.Folder
  With Fldr
    .ContentClass = ContentClass
    .Description = Description
    .DataSource.SaveTo Url, , _
                       adModeReadWrite, _
                       adCreateCollection Or adCreateOverwrite

  End With
  Set CreateFolder = Fldr

End Function
[VBScript]
Function CreateFolder( Url, ContentClass, Description )
  Set Fldr = CreateObject("CDO.Folder")
  With Fldr
    .ContentClass = ContentClass
    .Description  = Description
    On Error Resume Next
    .DataSource.Open Url, , adModeReadWrite

    If Err.Number <> 0 Then
      Err.Clear
      .DataSource.SaveTo Url, , _
                        adModeReadWrite, _
                       adCreateCollection Or adCreateOverWrite
      If Err.Number <> 0 Then
       ' Handle error
      End If
    End If
  End With

  On Error Goto 0
  Set CreateFolder = Fldr

End Function
[C++]
/*
 You must have the following paths in your
 INCLUDE path.
 %CommonProgramFiles%\system\ado
 %CommonProgramFiles%\microsoft shared\cdo

*/
#ifndef _CORE_EXAMPLE_HEADERS_INCLUDED
#define _CORE_EXAMPLE_HEADERS_INCLUDED
#import <msado15.dll> no_namespace
#import <cdoex.dll> no_namespace
#include <iostream.h>
#endif

IFolderPtr CreateFolder(bstr_t url, bstr_t contentclass, bstr_t description) {

   if(url == bstr_t(""))
      throw _com_error(E_POINTER);

   _ConnectionPtr Conn(__uuidof(Connection));
   IDataSourcePtr pDsrc(__uuidof(Folder));

   Conn->Provider = "ExOLEDB.DataSource";
   try {
      Conn->Open(url,bstr_t(),bstr_t(),-1);
   }
   catch(_com_error e) {
      throw e;
   }

   IFolderPtr pFldr = pDsrc;

   pFldr->ContentClass = contentclass;
   pFldr->Description  = description;

   try {
      pDsrc->SaveTo(
         url,
         variant_t((IDispatch*)Conn,true),
         adModeReadWrite,
         (RecordCreateOptionsEnum)
            (   adCreateCollection |
               adCreateOverwrite
            ),
         adOpenSource,
         bstr_t(),
         bstr_t());
   }
   catch(_com_error e) {
      cerr << "Error saving folder to store" << endl;
      throw e;
   }
   return pFldr;
}


DisplayName Property

The folder's display name.

[Visual Basic,VBScript]
Property DisplayName as String
read-only
[C++]
HRESULT get_DisplayName(BSTR* pVal);
[IDL]
HRESULT [propget] DisplayName([out,retval] BSTR* pVal);

Remarks

The display name for a folder might not correspond directly to the folder name contained in the folder item's URL. This property is read-only.


EmailAddress Property

The e-mail address of this folder.

[Visual Basic,VBScript]
Property EmailAddress as String
read-only
[C++]
HRESULT get_EmailAddress(BSTR* pVal);
[IDL]
HRESULT [propget] EmailAddress([out,retval] BSTR* pVal);

Remarks

A folder in a Microsoft Exchange public or private store can be configured as a mail recipient. If this folder has been configured to receive mail, this property returns the mail address.


Fields Property

The Fields collection for the object. This collection contains the properties for the folder stored in a Microsoft Exchange public or private store or a Web Storage System.

[Visual Basic,VBScript]
Property Fields as ADODB.Fields
read-only
[[C++]
HRESULT get_Fields(Fields** pVal);
IDL]
HRESULT [propget] Fields([out,retval] Fields** pVal);

Remarks

The ADO Fields object is a collection of ADO Field objects that pertain to this object. Each Field object holds a name/value pair defining some header field for the body part. The name is always a string, and the value is a VARIANT. The subtype of the VARIANT depends on the schema definition for the name. See the appropriate schema fields section of the reference for a list of valid fields to use along with a list of the VARIANT subtypes for each field.

Note When you use the ADO Fields.Update method, field values are updated only in memory. You must call IDataSource.Save to save the changes to the Web Storage System. To get the IDataSource interface, use the GetInterface method on the CDO object.

The fields that resize in this collection depend upon the specific implementation. Consult the appropriate COM class for details about available fields.


HasSubFolders Property

Indicates whether the folder contains subfolders.

[Visual Basic,VBScript]
Property HasSubFolders as Boolean
read-only
[C++]
HRESULT get_HasSubFolders(VARIANT_BOOL* pVal);
[IDL]
HRESULT [propget] HasSubFolders([out,retval] VARIANT_BOOL* pVal);


ItemCount Property

The number of nonfolder items in the folder.

[Visual Basic,VBScript]
Property ItemCount as Long
read-only
[C++]
HRESULT get_ItemCount(long* pVal);
[IDL]
HRESULT [propget] ItemCount([out,retval] long* pVal);


UnreadItemCount Property

The number of unread items in a folder.

[Visual Basic,VBScript]
Property UnreadItemCount as Long
read-only
[C++]
HRESULT get_UnreadItemCount(long* pVal);
[IDL]
HRESULT [propget] UnreadItemCount([out,retval] long* pVal);


VisibleCount Property

The number of visible nonfolder items in the folder. For this property, all nonfolder items that are not in the folder's associated contents table (often referred to as non-FAI messages) are visible.

[Visual Basic,VBScript]
Property VisibleCount as Long
read-only
[C++]
HRESULT get_VisibleCount(long* pVal);
[IDL]
HRESULT [propget] VisibleCount([out,retval] long* pVal);

Remarks

Items within this folder that have their DAV:ishidden property set to True are still reported in this count.


GetInterface Method

Returns the specified dual interface on the object.

[Visual Basic,VBScript]
Function GetInterface(ByVal Interface as String) as Object
[C++]
HRESULT GetInterface(BSTR Interface, IDispatch** pVal);
[IDL]
HRESULT GetInterface([in] BSTR Interface, [out,retval] IDispatch** pVal);
Interface
The name of the interface to obtain. The list of possible interfaces to return depends upon the COM class that provides the implementation.
pVal [C++,IDL]
On successful return, the passed address contains the requested object reference.

Remarks

The GetInterface method is primarily intended as a generic interface navigation aid to scripting languages that do not support such navigation directly.

The list of valid interface names to pass to GetInterface is dependent upon a specific implementation. As a general rule, the name of the desired interface should match the physical name of the interface as it appears in the type library or .idl file. Check the appropriate COM class for a list of exposed dual interfaces. If the object does not support the requested interface, an exception is raised with the HRESULT value of E_INVALIDARG.

Example

[VBScript]
Dim iFldr
Set iFldr = CreateObject("CDO.Folder")
' get config stored in ASP session object
Set iFldr.Configuration = Session("configobject")

' get idatasource
Dim iDsrc
Set iDsrc = iFldr.GetInterface("IDataSource")
' bind to inbox in store
' get a previously stored mailbox alias for the current user
strUserName = Session("mailboxalias")
iDSrc.Open "file:/.//backofficestorage/domain.microsoft.com/MBX/user1" & strUserName & "/Inbox/"

Response.Write("<i>you have " & iFldr.UnReadItemsCount & " unread items in your inbox</i>")
FldrName  = iFldr.DisplayName
strDescr  = iFldr.Description
' go on to display info about the folder
© 2000-2001 Microsoft Corporation. All rights reserved.


IFolderTree Interface

This interface allows you to create and modify folder trees in a Microsoft® Exchange 2000 Server MDBs.

IID
25150F47-5734-11D2-A593-00C04F990D8A
Extends
IDispatch

Member Summary

Properties

Name | Type | Description
DataSource (Read-Only) | IDataSource2 [C++,IDL] IDataSource2* | Returns the IDataSource2 interface on the object.
Fields (Read-Only) | [Visual Basic] ADODB.Fields [C++,IDL] Fields* | The object's Fields collection.
Name | [Visual Basic,VBScript] String [C++,IDL]BSTR | The name of the folder tree.
RootFolderURL (Read-only) | [Visual Basic,VBScript] String [C++,IDL] BSTR | Used to get a URL to the root folder of this tree.
StoreDBs (Read-only) | [Visual Basic,VBScript] Variant [C++,IDL] VARIANT | The list of URLs of public store databases that contain replicas of this public folder tree.
TreeType (Read-Only) | [Visual Basic,VBScript] CDOEXMFolderTreeType [C++,IDL]CDOEXMFolderTreeType | The folder type (MAPI or general purpose).

Methods

Name | Description
GetInterface | Returns the specified dual interface on the object.

Remarks

Folder trees can be distributed across several public MDBs.


Fields Property

The Fields collection for the object.

[Visual Basic]
Property Fields as ADODB.Fields
read-only
[C++]
HRESULT get_Fields(Fields** pVal);
[IDL]
HRESULT [propget] Fields([out,retval] Fields** pVal);

Remarks

The Fields property obtains a collection of ADO Field objects each of which contains a field relating to the FolderTree object.

Note When you use the ADO Fields.Update method, field values are updated only in memory. You must call IDataSource.Save to save the changes to the Web Storage System. To get the IDataSource interface, use the GetInterface method on the CDO object.


Name Property

Returns or sets the name of the folder tree.

[Visual Basic,VBScript]
Property Name as String
[C++]
HRESULT get_Name(BSTR* pVal);
HRESULT put_Name(BSTR pVal);
[IDL]
HRESULT [propget] Name([out,retval] BSTR* pVal);
HRESULT [propput] Name([in] BSTR Val);


RootFolderURL Property

Contains the URL to the root folder of this tree.

[Visual Basic,VBScript]
Property RootFolderURL as String
read-only
[C++]
HRESULT get_RootFolderURL(BSTR* pVal);

[IDL]
HRESULT [propget] RootFolderURL([out,retval] BSTR* pVal);


StoreDBs Property

The list of URLs of public store databases that contain replicas of this folder tree.

[Visual Basic,VBScript]
Property StoreDBs as Variant
read-only
[C++]
HRESULT get_StoreDBs (VARIANT* pVal);
[IDL]
HRESULT [propget] StoreDBs ([out,retval] VARIANT* pVal);


TreeType Property

Gets or sets the folder type for this folder tree.

[Visual Basic]
Property TreeType as CDOEXMFolderTreeType
[C++]
HRESULT get_TreeType(CDOEXMFolderTreeType* pVal);
HRESULT put_TreeType(CDOEXMFolderTreeType Val);
[IDL]
HRESULT [propget] TreeType([out,retval] CDOEXMFolderTreeType* pVal);
HRESULT [propput] TreeType([in] CDOEXMFolderTreeType Val);

Remarks

The CDOEXMFolderTreeType enumeration is provided for this property. It indicates whether the folder is a MAPI or non-MAPI folder tree.

See Also

CDOEXMFolderTreeType Enum

© 2000-2001 Microsoft Corporation. All rights reserved.


GetInterface Method

Returns the specified dual interface on the object.

[Visual Basic]
Function GetInterface(ByVal Interface as String) as Object
[C++]
HRESULT GetInterface(BSTR Interface, IDispatch** pVal);
[IDL]
HRESULT GetInterface([in] BSTR Interface, [out,retval] IDispatch** pVal);
Interface
The name of the interface to obtain.

Remarks

The GetInterface method is primarily intended as a generic interface navigation aid to scripting languages that do not support such navigation directly. Most COM classes that provide implementations of the IMessage interface expose additional dual interfaces that are accessible by scripting languages only through properties on the interface, such as BodyPart and DataSource, or through the GetInterface method. When properties do not exist on the interface to return these interfaces, the GetInterface method must be used.

The list of valid interface names to pass to GetInterface is dependent upon a specific implementation. As a general rule, the name of the desired interface should match the physical name of the interface as it appears in the type library or .idl file. Check the appropriate COM class for a list of exposed dual interfaces.

Example

The following examples demonstrate using GetInterface to return other interfaces on a FolderTree object.

[VBScript]
Dim ifoldertp, iDsrc

'Create an instance and get IFolderTree (IDispatch) back
Set ifoldertp = CreateObject("CDOEXM.FolderTree")

'Get IDataSource2 on the FolderTree Object
Set iDsrc = ifoldertp.GetInterface("IDataSource2")
[JScript]
var ifoldertp = new ActiveXObject("CDOEXM.FolderTree");
var iDsrc = ifoldertp .GetInterface("IDataSource2");


IIntegers Interface

Provides methods and properties for managing lists of integers. These lists of integers are used by properties of the IRecurrencePattern interface.

IID
CD00012E-8B95-11D1-82DB-00C04FB1625D
Extends
IDispatch

Member Summary

Properties

Name | Type | Description
Count (Read-only) | [Visual Basic,VBScript] Long [C++,IDL]Long | Returns the number of integers in the collection.
Item (Read-only) | [Visual Basic,VBScript] Long [C++,IDL]Long | Returns the integer value at the specified location in the collection.
_NewEnum (Read-only) | [Visual Basic,VBScript] (Used in For Each In) [C++,IDL] IUnknown* | Returns an IEnumVariant interface on an enumeration object. (This property is hidden from Visual Basic and is used in For Each In constructs.)

Methods

Name | Description
Delete | Deletes the integer at the specified location.
Add | Adds the specified integer to the collection.


Item Property

Returns the integer at the specified location in the collection.

[Visual Basic]
Property Item(Index as Long) as Long
read-only
[C++]
HRESULT get_Item(long Index, long *Value);
[IDL]
[propget, id(0)] HRESULT Item(long Index, [out, retval] long *Value);

Parameters

Index
The ordinal index of the integer to retrieve.
Value [C++,IDL]
On return, the integer requested from the collection.


Count Property

Returns the number of integers in the collection.

[Visual Basic]
Property Count as Long
read-only
[C++]
HRESULT get_Count(long* Count);
[IDL]
[propget, id(1)] HRESULT Count([out, retval] long *Count);

Parameters

Count [C++,IDL]
On return, the number of items in the collection.


_NewEnum Property

Returns the integer at the specified location in the collection.

[Visual Basic]
*Used in For Each In Constructs automatically
[C++]
HRESULT get__NewEnum(IUnknown **Value);
[IDL]
[propget, restricted, id(DISPID_NEWENUM)]
HRESULT _NewEnum([out, retval] IUnknown** Unknown);

Parameters

Unknown [C++, IDL]
The IUnknown interface on an object exposing the IEnumVARIANT interface.

Remarks

Call QueryInterface on the returned interface for the IEnumVARIANT (IID_IEnumVARIANT) interface on the object. You can then use this interface to enumerate the collection.

Microsoft® Visual Basic® programmers do not use this restricted property directly. It is used automatically in For Each In constructs.


Delete Method

Deletes the specified integer from the collection.

[Visual Basic]
Sub Delete(Value as Long)
[C++]
HRESULT Delete(long *Value);
[IDL]
[id(2)] HRESULT Delete([in] long *Value);

Parameters

Value
The pointer to the integer to delete.

Remarks

Note that you pass the address of the variable (ByRef) to the Delete method, rather than the value.


Add Method

Adds the specified integer to the collection.

[Visual Basic]
Sub Add(NewValue as Long)
[C++]
HRESULT Add(long NewValue);
[IDL]
[id(3)] HRESULT Add([in] long NewValue);

Parameters

NewValue
The value to add to the collection.


IItem Interface

The IItem interface defines methods and properties used to manage a generic item in a Microsoft® Web Storage System.

IID
CD000126-8B95-11D1-82DB-00C04FB1625D
Extends
IDispatch

Member Summary

Properties

Name | Type | Description
ChildCount (Read-Only) | [Visual Basic,VBScript]Long [C++,IDL] long | The number of items, including subfolders, in a folder.
Configuration | IConfiguration IConfiguration* | A reference to a Configuration object that defines the configuration information used by the object.
ContentClass | [Visual Basic,VBScript] String [C++,IDL]BSTR | The content class for the item.
CreationDate (Read-Only) | [Visual Basic,VBScript]Date [C++,IDL] DATE* | The date the item was created in the user's local file system or database.
DataSource (Read-Only) | IDataSource [C++,IDL] IDataSource* | Returns the IDataSource interface on the object.
DisplayName (Read-Only) | [Visual Basic,VBScript] String [C++,IDL] BSTR | The display name for the item.
Fields (Read-Only) | [Visual Basic,VBScript] ADODB.Fields [C++,IDL] Fields* | The Fields collection for the item.
IsCollection (Read-Only) | [Visual Basic,VBScript] Boolean [C++,IDL] VARIANT_BOOL* | Specifies whether or not the item is a collection.
IsHidden | [Visual Basic,VBScript] Boolean [C++,IDL] VARIANT_BOOL | Specifies whether or not the item is hidden from the user.
IsStructuredDocument (Read-Only) | [Visual Basic,VBScript] Boolean [C++,IDL] VARIANT_BOOL* | Specifies whether or not the item is a structured document.
LastModified (Read-Only) | [Visual Basic,VBScript]Date [C++,IDL] DATE* | The time that the item was last modified.
ObjectCount (Read-Only) | [Visual Basic,VBScript]Long [C++,IDL] long | The number of nonfolder items in the folder, including any hidden items.
ParentURL (Read-Only) | [Visual Basic,VBScript]String [C++,IDL] BSTR* | The absolute URL of the parent folder.
VisibleCount (Read-Only) | [Visual Basic,VBScript]Long [C++,IDL] long | The number of visible noncollection items in the folder.

Methods

Name | Description
GetInterface | Returns the specified interface on this object.
GetStream | Returns the stream for the resource in an ADO Stream (_Stream interface) object.

Remarks

COM classes that provide implementations of the IItem interface can be used to bind and manage any item in a Web Storage System, including collections (folders) and resources. The properties defined on the interface are common properties defined by the urn:content-classes:item content class, and all store content classes extend this base class.

If the bound item is a stream-based content class, such as urn:content-classes:document or urn:content-classes:message, the IItem.GetStream method can be used to access the associated content stream.

Properties on the interface have type and semantic definitions identical to the corresponding schema property. For example, the IItem.ObjectCount interface property has the same type and semantic definition as the corresponding DAV:objectcount schema property.


ChildCount Property

The number of items, including subfolders, in the folder.

[Visual Basic,VBScript]
Property ChildCount as Long
read-only
[C++]
HRESULT get_ChildCount(long* pVal);
[IDL]
HRESULT [propget] ChildCount([out,retval] long* pVal);

Remarks

This property is also available as the DAV:childcount schema property in the Fields collection.

See Also

IsCollection

© 2000-2001 Microsoft Corporation. All rights reserved.


Configuration Property

A reference to a Configuration object in which configuration information for the object is defined.

[Visual Basic,VBScript]
Property Configuration as IConfiguration
[C++]
HRESULT get_Configuration(IConfiguration** pVal);
HRESULT put_Configuration(IConfiguration* Val);
[IDL]
HRESULT [propget] Configuration([out,retval] IConfiguration** pVal);
HRESULT [propput] Configuration([in] IConfiguration* Val);

Remarks

A Configuration object should be shared among other CDO objects to define a single configuration for the entire set.


ContentClass Property

The content class for the item.

[Visual Basic,VBScript]
Property ContentClass as String
[C++]
HRESULT get_ContentClass(BSTR* pVal);
HRESULT put_ContentClass(BSTR Val);
[IDL]
HRESULT [propget] ContentClass([out,retval] BSTR* pVal);
HRESULT [propput] ContentClass([in] BSTR Val);

Remarks

This property is also available as the DAV:contentclass schema property in the Fields collection.

See Also

Content Classes

© 2000-2001 Microsoft Corporation. All rights reserved.


CreationDate Property

The date that the resource was created in the user's local file system or database.

[Visual Basic,VBScript]
Property CreationDate as Date
read-only
[C++]
HRESULT get_CreationDate(DATE* pVal);
[IDL]
HRESULT [propget] CreationDate([out,retval] DATE* pVal);

Remarks

This property is also available as the DAV:creationdate schema property, accessible from the Fields collection.


DataSource Property

Returns the IDataSource interface on the object.

[Visual Basic,VBScript]
Property DataSource as IDataSource
read-only
[C++]
HRESULT get_DataSource(IDataSource** pVal);
[IDL]
HRESULT [propget] DataSource([out,retval] IDataSource** pVal);

Remarks

This property returns the IDataSource interface on the object. The IDataSource interface on the object is used to open items from and save items to the Web Storage System and CDO objects.

If the IDataSource interface is not implemented by the object, the COM exception E_NOTIMPL is raised.


DisplayName Property

The item's display name.

[Visual Basic,VBScript]
Property DisplayName as String
[C++]
HRESULT get_DisplayName(BSTR* pVal);
HRESULT put_DisplayName(BSTR pVal);
[IDL]
HRESULT [propget] DisplayName([out,retval] BSTR* pVal);
HRESULT [propput] DisplayName([in] BSTR pVal);

Remarks

The display name is generated in many cases and can contain either the subject of a message or the fileas property value for a contact.

This property is also available as the DAV:displayname schema property, accessible from the Fields collection.


Fields Property

The property collection for the object.

[Visual Basic,VBScript]
Property Fields as ADODB.Fields
read-only
[C++]
HRESULT get_Fields(Fields** pVal);
[IDL]
HRESULT [propget] Fields([out,retval] Fields** pVal);

Remarks

The properties for the item are stored in an ADO Fields collection object. Each Field object holds a name/value pair defining some property of the item. The name is always a string, and the value is a VARIANT. The subtype of the VARIANT depends on the schema definition for the name. See the appropriate schema fields section of the reference for a list of valid fields to use along with a list of the VARIANT subtypes for each field.

Many fields available in this collection can be set or retrieved using a corresponding property on the IItem interface.

The fields used in this collection depend upon the specific implementation. Consult the appropriate COM class or DAV:contentclass value for details about available fields.

Note When you use the ADO Fields.Update method, field values are updated only in memory. You must call IDataSource.Save to save the changes to the Web Storage System. To get the IDataSource interface, use the GetInterface method on the CDO object.


IsCollection Property

Specifies whether or not the item is a collection.

[Visual Basic,VBScript]
Property IsCollection as Boolean
read-only
[C++]
HRESULT get_IsCollection(VARIANT_BOOL* pVal);
[IDL]
HRESULT [propget] IsCollection([out,retval] VARIANT_BOOL* pVal);

Remarks

This property is also available as the DAV:iscollection schema property in the Fields collection.


IsHidden Property

Specifies whether or not the item is hidden.

[Visual Basic,VBScript]
Property IsHidden as Boolean
[C++]
HRESULT get_IsHidden(VARIANT_BOOL* pVal);
HRESULT put_IsHidden(VARIANT_BOOL pVal);
[IDL]
HRESULT [propget] IsHidden([out,retval] VARIANT_BOOL* pVal);
HRESULT [propput] IsHidden([in] VARIANT_BOOL pVal);

Remarks

This property is also available as the DAV:ishidden schema property accessible in the Fields collection.

Note This property only has the intended result when the item is created before calling IDataSource::Save. You cannot use IsHidden to toggle an existing item between being hidden and not hidden.


IsStructuredDocument Property

Specifies whether or not the item is a structured document.

[Visual Basic,VBScript]
Property IsStructuredDocument as Boolean
read-only
[C++]
HRESULT get_IsStructuredDocument(VARIANT_BOOL* pVal);
[IDL]
HRESULT [propget] IsStructuredDocument([out,retval] VARIANT_BOOL* pVal);

Remarks

This property is also available as the DAV:isstructureddocument schema property accessible in the Fields collection.


LastModified Property

The time that the item was last modified.

[Visual Basic,VBScript]
Property LastModified as String
read-only
[C++]
HRESULT get_LastModified(BSTR* pVal);
[IDL]
HRESULT [propget] LastModified([out,retval] BSTR* pVal);


ObjectCount Property

The number of nonfolder items in a folder, including any hidden items.

[Visual Basic,VBScript]
Property ObjectCount as Long
read-only
[C++]
HRESULT get_ObjectCount(long* pVal);
[IDL]
HRESULT [propget] ObjectCount([out,retval] long* pVal);

Remarks

This property is also available as the DAV:objectcount schema property accessible in the Fields collection.

See Also

VisibleCount

© 2000-2001 Microsoft Corporation. All rights reserved.


ParentURL Property

The absolute URL of the item's parent collection.

[Visual Basic,VBScript]
Property ParentURL as String
read-only
[C++]
HRESULT get_ParentURL(BSTR* pVal);
[IDL]
HRESULT [propget] ParentURL([out,retval] BSTR* pVal);


VisibleCount Property

The number of visible noncollection items in the folder.

[Visual Basic,VBScript]
Property VisibleCount as Long
read-only
[C++]
HRESULT get_VisibleCount(long* pVal);
[IDL]
HRESULT [propget] VisibleCount([out,retval] long* pVal);

Remarks

This property is the same as the DAV:visiblecount schema property accessible in the Fields collection.

See Also

ObjectCount

© 2000-2001 Microsoft Corporation. All rights reserved.


GetInterface Method

Returns the specified dual interface on the object.

[Visual Basic,VBScript]
Function GetInterface(ByVal Interface as String) as Object
[C++]
HRESULT GetInterface( BSTR Interface, IDispatch** ppUnknown);
[IDL]
HRESULT GetInterface([in] BSTR Interface, [out,retval] IDispatch** ppUnknown);
Interface
The name of the interface to obtain. The list of possible interfaces to return depends upon the COM class that provides the implementation.
ppUnknown [C++,IDL]
If the method succeeds, then on return, the address passed holds a reference to the requested interface.

Remarks

The GetInterface method is primarily intended as a generic interface navigation aid to scripting languages that do not support such navigation directly.

The list of valid interface names to pass to GetInterface is dependent upon a specific implementation. As a general rule, the name of the desired interface should match the physical name of the interface as it appears in the type library or .idl file. Check the appropriate COM class for a list of exposed dual interfaces. If the requested interface is not supported by the object, an exception is raised with the HRESULT value of E_INVALIDARG.

Example

[VBScript]
Dim iAdrse
Set iAdrse = CreateObject("CDO.Addressee")
Dim iDsrc
Set iDsrc = iAdrse.GetInterface("IDataSource")


GetStream Method

Returns the item's content stream.

[Visual Basic,VBScript]
Function GetStream() as ADODB.Stream
[C++]
HRESULT GetStream(_Stream** pVal);
[IDL]
HRESULT GetStream([out,retval] _Stream** pVal);

Remarks

The GetStream method returns a _Stream object reference on an ADO Stream object containing the content stream for the item. Only items that are of a stream-based content class have associated streams. If you call GetStream on a collection-based item, an error is raised.

If you modify the content in the returned Stream object, you commit these changes by calling the _Stream::Flush method. If the Flush method is not called, changes are lost when the Stream object is destroyed.


IMailBox Interface

Provides access to a hierarchy of folders belonging to a person.

IID
CD000125-8B95-11D1-82DB-00C04FB1625D
Extends
IDispatch

Member Summary

Properties

Name | Type | Description
BaseFolder (Read-Only) | [Visual Basic,VBScript] String [C++,IDL] BSTR | Returns the URL to the primary folder in a mailbox, usually the inbox.
Calendar (Read-Only) | [Visual Basic,VBScript] String [C++,IDL] BSTR | Returns the URL to the folder containing items of calendar content.
Contacts (Read-Only) | [Visual Basic,VBScript] String [C++,IDL] BSTR | Returns the URL to the folder containing items of contact content.
DeletedItems (Read-Only) | [Visual Basic,VBScript] String [C++,IDL] BSTR | Returns the URL to the folder containing deleted items.
Drafts (Read-Only) | [Visual Basic,VBScript] String [C++,IDL] BSTR | Returns the URL to the folder containing items being composed.
Forms (Read-Only) | [Visual Basic,VBScript] String [C++,IDL] BSTR | Returns the URL to the folder containing items of form content.
Inbox (Read-Only) | [Visual Basic,VBScript] String [C++,IDL] BSTR | Returns the URL to the inbox folder.
Journal (Read-Only) | [Visual Basic,VBScript] String [C++,IDL] BSTR | Returns the URL to the folder containing items of journal content. (Not implemented)
Notes (Read-Only) | [Visual Basic,VBScript] String [C++,IDL] BSTR | Returns the URL to the folder containing items of notes content. (Not implemented)
Outbox (Read-Only) | [Visual Basic,VBScript] String [C++,IDL] BSTR | Returns the URL to the folder containing items to be sent, or not yet sent.
RootFolder (Read-Only) | [Visual Basic,VBScript] String [C++,IDL] BSTR | Returns the URL to the folder highest in the hierarchy.
SentItems (Read-Only) | [Visual Basic,VBScript] String [C++,IDL] BSTR | Returns the URL to the folder containing sent items.
Tasks (Read-Only) | [Visual Basic,VBScript] String [Visual Basic,VBScript] [C++,IDL] BSTR | Returns the URL to the folder containing items of task content. (Not implemented)

Remarks

The IMailbox interface provides quick access to the folders in a user's mailbox.

Example

This example shows how to use IMailbox with the CDO Person object to get the URL of a person's inbox when you know the e-mail address.

[VBScript]
email = WScript.Arguments(0)

Set Person = CreateObject("CDO.Person")

strURL = "mailto:" & email

Person.DataSource.Open strURL

Set Mailbox = Person.GetInterface("IMailbox")

WScript.Echo "URL to inbox for " & email & " is: " & Mailbox.Inbox


BaseFolder Property

Returns the URL to the primary folder in a mailbox, usually the inbox.

[Visual Basic,VBScript]
Property BaseFolder as String
read-only
[C++]
HRESULT get_BaseFolder(BSTR* pVal);
[IDL]
HRESULT [propget] BaseFolder([out,retval] BSTR* pVal);


Calendar Property

Returns the URL to the folder containing items of calendar content.

[Visual Basic,VBScript]
Property Calendar as String
read-only
[C++]
HRESULT get_Calendar(BSTR* pVal);
[IDL]
HRESULT [propget] Calendar([out,retval] BSTR* pVal);


Contacts Property

Returns the URL to the folder containing items of contact content.

[Visual Basic,VBScript]
Property Contacts as String
read-only
[C++]
HRESULT get_Contacts(BSTR* pVal);
[IDL]
HRESULT [propget] Contacts([out,retval] BSTR* pVal);


DeletedItems Property

Returns the URL to the folder containing deleted items.

[Visual Basic,VBScript]
Property DeletedItems as String
read-only
[C++]
HRESULT get_DeletedItems(BSTR* pVal);
[IDL]
HRESULT [propget] DeletedItems([out,retval] BSTR* pVal);


Drafts Property

Returns the URL to the folder containing items being composed.

[Visual Basic,VBScript]
Property Drafts as String
read-only
[C++]
HRESULT get_Drafts(BSTR* pVal);
[IDL]
HRESULT [propget] Drafts([out,retval] BSTR* pVal);


Forms Property

Returns the URL to the folder containing items of form content.

[Visual Basic,VBScript]
Property Forms as String
read-only
[C++]
HRESULT get_Forms(BSTR* pVal);
[IDL]
HRESULT [propget] Forms([out,retval] BSTR* pVal);


Inbox Property

Returns the URL to the inbox folder.

[Visual Basic,VBScript]
Property Inbox as String
read-only
[C++]
HRESULT get_Inbox(BSTR* pVal);
[IDL]
HRESULT [propget] Inbox([out,retval] BSTR* pVal);


Journal Property

Returns the URL to the folder containing items of journal content.

Note This property is not yet implemented.

[Visual Basic,VBScript]
Property Journal as String
read-only
[C++]
HRESULT get_Journal(BSTR* pVal);
[IDL]
HRESULT [propget] Journal([out,retval] BSTR* pVal);


Notes Property

Returns the URL to the folder containing items of notes content.

Note This property is not yet implemented.

[Visual Basic,VBScript]
Property Notes as String
read-only
[C++]
HRESULT get_Notes(BSTR* pVal);
[IDL]
HRESULT [propget] Notes([out,retval] BSTR* pVal);


Outbox Property

Returns the URL to the folder containing items to be sent, or not yet sent.

[Visual Basic,VBScript]
Property Outbox as String
read-only
[C++]
HRESULT get_Outbox(BSTR* pVal);
[IDL]
HRESULT [propget] Outbox([out,retval] BSTR* pVal);


RootFolder Property

Returns the URL to the folder highest in the hierarchy, usually the Mailbox.

[Visual Basic,VBScript]
Property RootFolder as String
read-only
[C++]
HRESULT get_RootFolder(BSTR* pVal);
[IDL]
HRESULT [propget] RootFolder([out,retval] BSTR* pVal);


SentItems Property

Returns the URL to the folder containing sent items.

[Visual Basic,VBScript]
Property SentItems as String
read-only
[C++]
HRESULT get_SentItems(BSTR* pVal);
[IDL]
HRESULT [propget] SentItems([out,retval] BSTR* pVal);


Tasks Property

Returns the URL to the folder containing items of task content.

Note This property is not yet implemented.

[Visual Basic,VBScript]
Property Tasks as String
read-only
[C++]
HRESULT get_Tasks(BSTR* pVal);
[IDL]
HRESULT [propget] Tasks([out,retval] BSTR* pVal);


IMailBoxStore Interface

This interface provides access to the administrative properties of a mailbox-enabled recipient. It also provides methods to create, move, and delete mailboxes. See Managing Mail Recipients for overview information.

IID
25150F41-5734-11d2-A593-00C04F990D8A
Extends
IDispatch

Member Summary

Properties

Name | Type | Description
DaysBeforeGarbageCollection | [Visual Basic,VBScript] Long [C++,IDL]Long | The number of days deleted mail is retained before it is permanently deleted.
Delegates | [Visual Basic,VBScript] Variant [C++,IDL] VARIANT | The list of URLs of all users that have access to the mailbox.
EnableStoreDefaults | [Visual Basic,VBScript] Boolean [C++,IDL] VARIANT_BOOL | Dictates whether to use only default store values for storage limits, or to use other properties pertaining to the mailbox.
GarbageCollectOnlyAfterBackup | [Visual Basic,VBScript] Boolean [C++,IDL] VARIANT_BOOL | Dictates whether deleted messages can only be permanently deleted after the mailbox has been backed up.
Hardlimit | [Visual Basic,VBScript] Long [C++,IDL]Long | The mailbox's maximum size, in kilobytes (KB), over which sending and receiving is restricted.
HomeMDB (Read-Only) | [Visual Basic,VBScript] String [C++,IDL] BSTR | The URL of the store for the recipient.
OverQuotaLimit | [Visual Basic,VBScript] Long [C++,IDL]Long | The maximum size, in KB, over the StoreQuota property size upon which sending mail is disabled.
OverrideStoreGarbageCollection | [Visual Basic,VBScript] Boolean [C++,IDL] VARIANT_BOOL | Dictates whether the store should be prevented from permanently deleting deleted messages.
RecipientLimit | [Visual Basic,VBScript] Long [C++,IDL]Long | Maximum number of people to whom the recipient can send e-mail.
StoreQuota | [Visual Basic,VBScript] Long [C++,IDL]Long | The maximum size, in KB, allowed for the mailbox.

Methods

Name | Description
CreateMailBox | Creates a mailbox at a specified URL.
DeleteMailBox | Deletes a mailbox.
MoveMailBox | Moves a mailbox to a specified URL.

Example (CDOEXM)

[Visual Basic]
Function CreateMailboxCDOPerson(strFirstName As String, _
                                   strLastName As String, _
                                   strHomeMDBUrl As String) As Boolean
'strHomeMDBUrl should look like this
'strHomeMDBUrl = "CN=Mailbox Store (MYSTORE),CN=First Storage Group,
'                 CN=InformationStore,CN=MYSTORE,CN=Servers,
'                 CN=First Administrative Group,CN=Administrative Groups,
'                 CN=IASI,CN=Microsoft Exchange,CN=Services,CN=Configuration,
'                 DC=mydomain,DC=extest,DC=microsoft,DC=com"

    Dim oPerson         As New CDO.Person
    Dim oMailbox        As CDOEXM.IMailboxStore
    Dim strUserName     As String
    Dim strURL          As String
    Dim strContainerName As String
    Dim Result       As Boolean

    Result = True

    strUserName = strFirstName & strLastName

    strContainerName = "Users"
    ' Create URL for the user
    Result = Result And CreateUserURL(strURL, strContainerName, False, strUserName)

    oPerson.FirstName = strFirstName
    oPerson.LastName = strLastName

    oPerson.DataSource.SaveTo strURL
    Result = Result And CheckError("SaveTo " & strURL)

    Set oPerson = New CDO.Person
    ' Bind
    oPerson.DataSource.Open strURL
    Result = Result And CheckError("Bind to CDO User " & strUserName)

    ' Create Mailbox
    Set oMailbox = oPerson
    oMailbox.CreateMailbox strHomeMDBUrl
    Result = Result And CheckError("Create Mailbox for CDO User " & strUserName)

    ' Save
    oPerson.DataSource.Save
    Result = Result And CheckError("Save CDO User " & strUserName)

    'CleanUp
    Set oPerson = Nothing
    Set oMailbox = Nothing

    CreateMailboxCDOPerson = Result
End Function

Example (ADSI)

[Visual Basic]
Function ADSICreateMailBoxRecipient(ServerName As String, _
                                    DomainName As String, _
                                    emailname As String, _
                                    FirstName As String, _
                                    LastName As String) As Integer

'ServerName is something like "MyServer6"
'DomainName is something like "DC=MYDOMAIN3,DC=microsoft,DC=com"
'emailname is something like "jamessmith"

'this assumes the MDB to be "Private MDB"

Dim objUser As IADsUser
Dim objContainer As IADsContainer
Dim objMailbox As CDOEXM.IMailboxStore
Dim recipname As String, recip As String

recip = "CN=" & emailname

' get the container
Set objContainer = GetObject("LDAP://" + ServerName + "/" + _
                            "CN=users," + DomainName)

' create a recipient
Set objUser = objContainer.Create("User", recip)
objUser.Put "samAccountName", emailname
objUser.Put "sn", LastName
objUser.Put "givenName", FirstName
objUser.Put "userPrincipalName", emailname

objUser.SetInfo
objUser.SetPassword "password"  'let user change it later
objUser.AccountDisabled = False

Set objMailbox = objUser.GetInterface("IMailboxStore")

'Create a mailbox for the recipient
'You cannot create a mailbox using ADSI, so use CDOEXM
objMailbox.CreateMailbox "LDAP://" + ServerName + _
                         "/CN=Private MDB" + _
                         ",CN=First Storage Group,CN=InformationStore,CN=" + _
                         ServerName + _
                         ",CN=Servers,CN=First Administrative Group," + _
                         "CN=Administrative Groups,CN=First Organization," + _
                         "CN=Microsoft Exchange,CN=Services," + _
                         "CN=Configuration," + DomainName
objUser.SetInfo

End Function
© 2000-2001 Microsoft Corporation. All rights reserved.


DaysBeforeGarbageCollection Property

This property specifies the number of days deleted mail is retained before it is permanently deleted.

[Visual Basic,VBScript]
Property DaysBeforeGarbageCollection as Long
[C++]
HRESULT get_DaysBeforeGarbageCollection(long* pVal);
HRESULT put_DaysBeforeGarbageCollection(long Val);
[IDL]
HRESULT [propget] DaysBeforeGarbageCollection([out,retval] long* pVal);
HRESULT [propput] DaysBeforeGarbageCollection([in] long Val);

Remarks

The default value for this property is 0.

Example (ADSI)

[Visual Basic]
Sub Set_Cleanup(ServerName As String, _
                DomainName As String, _
                recipname As String)

'ServerName is something like "MyServer6"
'DomainName is something like "DC=MYDOMAIN3,DC=microsoft,DC=com"
'recipname is something like "jamessmith"

Dim objUser As IADsUser
Dim objMailbox As CDOEXM.IMailboxStore

Set objUser = GetObject("LDAP://" + ServerName + _
                        "/CN=" + recipname + _
                        ",CN=users," + DomainName)

Set objMailbox = objUser
If objMailbox.HomeMDB = "" Then
   MsgBox "No mailbox found."
Else
   objMailbox.GarbageCollectOnlyAfterBackup = True
   objMailbox.DaysBeforeGarbageCollection = 7
   'commit the changes
   objUser.SetInfo
End If

End Sub
© 2000-2001 Microsoft Corporation. All rights reserved.


Delegates Property

This property specifies the list of URLs of all users that have access to the mailbox.

[Visual Basic,VBScript]
Property Delegates as Variant
[C++]
HRESULT get_Delegates(VARIANT* pVal);
HRESULT put_Delegates(VARIANT Val);
[IDL]
HRESULT [propget] Delegates([out,retval] VARIANT* pVal);
HRESULT [propput] Delegates([in] VARIANT Val);

Remarks

The default value for this property is NULL.


EnableStoreDefaults Property

This property specifies whether to use only default store values for storage limits.

[Visual Basic,VBScript]
Property EnableStoreDefaults as Boolean
[C++]
HRESULT get_EnableStoreDefaults (VARIANT_BOOL* pVal);
HRESULT put_EnableStoreDefaults (BOOL Val);
[IDL]
HRESULT [propget] EnableStoreDefaults ([out,retval] VARIANT_BOOL* pVal);
HRESULT [propput] EnableStoreDefaults ([in] VARIANT_BOOL Val);

Remarks

If this property is true, only the default store values for storage limits are used; if this property is false, the store limit properties are used. The limit properties are:

HardLimit,

OverQuotaLimit, and

StoreQuota.

The default value for this property is VT_EMPTY (no value).


GarbageCollectOnlyAfterBackup Property

This property specifies whether deleted messages can only be permanently deleted after the mailbox has been backed up.

[Visual Basic,VBScript]
Property GarbageCollectOnlyAfterBackup as Boolean
[C++]
HRESULT get_GarbageCollectOnlyAfterBackup(VARIANT_BOOL* pVal);
HRESULT put_GarbageCollectOnlyAfterBackup(VARIANT_BOOL Val);
[IDL]
HRESULT [propget] GarbageCollectOnlyAfterBackup([out,retval] VARIANT_BOOL* pVal);
HRESULT [propput] GarbageCollectOnlyAfterBackup([in] VARIANT_BOOL Val);

Remarks

If this property is true, deleted messages can only be permanently deleted after the mailbox has been backed up; if this property is false, deleted messages can be permanently deleted at any time.

The default value for this property is false.


Hardlimit Property

This property specifies the maximum mailbox size, in KB, over which sending and receiving mail is disabled.

[Visual Basic,VBScript]
Property HardLimit as Long
[C++]
HRESULT get_HardLimit(long* pVal);
HRESULT put_HardLimit(long Val);
[IDL]
HRESULT [propget] HardLimit([out,retval] long* pVal);
HRESULT [propput] HardLimit([in] long Val);

Remarks

Defaults for quota values are set in the IMailboxStoreDB interface. For more information, see the EnableStoreDefaults, OverQuotaLimit, and StoreQuota properties.

Example (CDOEXM)

[Visual Basic]
Sub Set_Limits(ServerName As String, _
               DomainName As String, _
               recipname As String)

    'ServerName is something like "MyServer6"
    'DomainName is something like "DC=MYDOMAIN3,DC=microsoft,DC=com"
    'recipname is something like "jamessmith"

    Dim objPerson As New CDO.Person
    Dim objMailbox As CDOEXM.IMailboxStore

    objPerson.DataSource.Open "LDAP://" + ServerName + _
                                "/CN=" + recipname + _
                                ",CN=users," + DomainName

    Set objMailbox = objPerson
    If objMailbox.HomeMDB = "" Then
       MsgBox "No Mailbox found."
    Else
       objMailbox.StoreQuota = 10
       objMailbox.OverQuotaLimit = 2
       objMailbox.HardLimit = 1
       objPerson.DataSource.Save
       MsgBox "Mailbox limits for " + recipname + " set successfully"
    End If

End Sub
© 2000-2001 Microsoft Corporation. All rights reserved.


HomeMDB Property

This property specifies the URL of the store for the recipient.

[Visual Basic,VBScript]
Property HomeMDB as String
Read-only
[C++]
HRESULT get_HomeMDB(BSTR* pVal);
[IDL]
HRESULT [propget] HomeMDB([out,retval] BSTR* pVal);

Remarks

The default value for this property is NULL.

This value is represented as a DN value. See E-mail Addresses Stored as Active Directory Paths for more information.


OverQuotaLimit Property

The maximum size of a mailbox, in KB, before sending messages is suspended.

[Visual Basic,VBScript]
Property OverQuotaLimit as Long
[C++]
HRESULT get_OverQuotaLimit(long* pVal);
HRESULT put_OverQuotaLimit(long Val);
[IDL]
HRESULT [propget] OverQuotaLimit([out,retval] long* pVal);
HRESULT [propput] OverQuotaLimit([in] long Val);

Remarks

Defaults for quota values are set in the IMailboxStoreDB interface. See also the EnableStoreDefaults and StoreQuota properties. For an example, see the Hardlimit property.


OverrideStoreGarbageCollection Property

This property defines whether the store will be prevented from permanently deleting deleted messages.

[Visual Basic,VBScript]
Property OverrideStoreGarbageCollection as Boolean
[C++]
HRESULT get_OverrideStoreGarbageCollection(VARIANT_BOOL* pVal);
HRESULT put_OverrideStoreGarbageCollection(VARIANT_BOOL Val);
[IDL]
HRESULT [propget] OverrideStoreGarbageCollection([out,retval] VARIANT_BOOL* pVal);
HRESULT [propput] OverrideStoreGarbageCollection([in] VARINAT_BOOL Val);

Remarks

If this property is true, the store is prevented from permanently deleting deleted messages; if this property is false, the store can permanently delete deleted messages.

The default value for this property is false.


RecipientLimit Property

The maximum number of people to whom the recipient can send e-mail.

[Visual Basic,VBScript]
Property RecipientLimit as Long
[C++]
HRESULT get_RecipientLimit (long* pVal);
HRESULT put_RecipientLimit (long Val);
[IDL]
HRESULT [propget] RecipientLimit ([out,retval] long* pVal);
HRESULT [propput] RecipientLimit ([in] long Val);

Remarks

This is designed to limit the recipient's e-mail broadcast range.

The default value for this property is -1 (no limit).

See also the EnableStoreDefaults property.


StoreQuota Property

This property specifies the maximum size, in KB, allowed for the mailbox.

[Visual Basic,VBScript]
Property StoreQuota as Long
[C++]
HRESULT get_StoreQuota(long* pVal);
HRESULT put_StoreQuota(long Val);
[IDL]
HRESULT [propget] StoreQuota([out,retval] long* pVal);
HRESULT [propput] StoreQuota([in] long Val);

Remarks

Above this limit the recipient will get a warning.

Defaults for quota values are set in the IMailboxStoreDB interface. See also the EnableStoreDefaults property.

See also the OverQuotaLimit and HardLimit properties.

Example

See the Hardlimit property

© 2000-2001 Microsoft Corporation. All rights reserved.


CreateMailBox Method

This method creates a mailbox at a specified URL.

[Visual Basic,VBScript]
Sub CreateMailBox(HomeMDBURL As String)
[C++]
HRESULT CreateMailBox(BSTR HomeMDBURL);
[IDL]
HRESULT CreateMailBox([in] BSTR HomeMDBURL);
HomeMDBURL
The URL to the new mailbox. This value can be saved as a standard e-mail name or as a DN value. See E-mail Addresses Stored as Active Directory Paths for more information.

Remarks

The store creates the actual mailbox the first time someone either sends mail to the mailbox or connects to the mailbox.

Example (CDO)

[Visual Basic]
Function CreateMailboxCDOPerson(strFirstName As String, _
                                   strLastName As String, _
                                   strHomeMDBUrl As String) As Boolean
'strHomeMDBUrl should look like this
'strHomeMDBUrl = "CN=Mailbox Store (MYSTORE),CN=First Storage Group,
'                 CN=InformationStore,CN=MYSTORE,CN=Servers,
'                 CN=First Administrative Group,CN=Administrative Groups,
'                 CN=IASI,CN=Microsoft Exchange,CN=Services,CN=Configuration,
'                 DC=mydomain,DC=extest,DC=microsoft,DC=com"

    Dim oPerson         As New CDO.Person
    Dim oMailbox        As CDOEXM.IMailboxStore
    Dim strUserName     As String
    Dim strURL          As String
    Dim strContainerName As String
    Dim Result       As Boolean

    Result = True

    strUserName = strFirstName & strLastName

    strContainerName = "Users"
    ' Create URL for the user
    Result = Result And CreateUserURL(strURL, strContainerName, False, strUserName)

    oPerson.FirstName = strFirstName
    oPerson.LastName = strLastName

    oPerson.DataSource.SaveTo strURL
    Result = Result And CheckError("SaveTo " & strURL)

    Set oPerson = New CDO.Person
    ' Bind
    oPerson.DataSource.Open strURL
    Result = Result And CheckError("Bind to CDO User " & strUserName)

    ' Create Mailbox
    Set oMailbox = oPerson
    oMailbox.CreateMailbox strHomeMDBUrl
    Result = Result And CheckError("Create Mailbox for CDO User " & strUserName)

    ' Save
    oPerson.DataSource.Save
    Result = Result And CheckError("Save CDO User " & strUserName)

    'CleanUp
    Set oPerson = Nothing
    Set oMailbox = Nothing

    CreateMailboxCDOPerson = Result
End Function

Example (ADSI)

[Visual Basic]
Function ADSICreateMailBoxRecipient(ServerName As String, _
                                    DomainName As String, _
                                    emailname As String, _
                                    FirstName As String, _
                                    LastName As String) As Integer

'ServerName is something like "MyServer6"
'DomainName is something like "DC=MYDOMAIN3,DC=microsoft,DC=com"
'emailname is something like "jamessmith"

'this assumes the MDB to be "Private MDB"

Dim objUser As IADsUser
Dim objContainer As IADsContainer
Dim objMailbox As CDOEXM.IMailboxStore
Dim recipname As String, recip As String

recip = "CN=" & emailname

' get the container
Set objContainer = GetObject("LDAP://" + ServerName + "/" + _
                            "CN=users," + DomainName)

' create a recipient
Set objUser = objContainer.Create("User", recip)
objUser.Put "samAccountName", emailname
objUser.Put "sn", LastName
objUser.Put "givenName", FirstName
objUser.Put "userPrincipalName", emailname

objUser.SetInfo
objUser.SetPassword "password"  'let user change it later
objUser.AccountDisabled = False

Set objMailbox = objUser

'Create a mailbox for the recipient
'You cannot create a mailbox using ADSI, so use CDOEXM
objMailbox.CreateMailbox "LDAP://" + ServerName + _
                         "/CN=Private MDB" + _
                         ",CN=First Storage Group,CN=InformationStore,CN=" + _
                         ServerName + _
                         ",CN=Servers,CN=First Administrative Group," + _
                         "CN=Administrative Groups,CN=First Organization," + _
                         "CN=Microsoft Exchange,CN=Services," + _
                         "CN=Configuration," + DomainName
objUser.SetInfo

End Function
© 2000-2001 Microsoft Corporation. All rights reserved.


DeleteMailBox Method

This method deletes a mailbox.

[Visual Basic,VBScript]
Sub DeleteMailBox
[C++]
HRESULT DeleteMailBox();
[IDL]
HRESULT DeleteMailBox();

Remarks

Example (CDO)

[Visual Basic]
Function DeleteMailboxCDOPerson(strFirstName As String, _
                                   strLastName As String) As Boolean

    Dim oPerson         As New CDO.Person
    Dim oMailbox        As CDOEXM.IMailboxStore
    Dim strUserName     As String
    Dim strURL          As String
    Dim strContainerName As String
    Dim Result       As Boolean

    Result = True

    strUserName = strFirstName & strLastName
    strContainerName = "Users"
    ' Create URL for the user
    Result = Result And CreateUserURL(strURL, strContainerName, False, strUserName)

    Set oPerson = New CDO.Person
    ' Bind
    oPerson.DataSource.Open strURL
    Result = Result And CheckError("Bind to CDO User " & strUserName)

    ' Delete Mailbox
    Set oMailbox = oPerson
    oMailbox.DeleteMailbox
    Result = Result And CheckError("Delete Mailbox for CDO User " & strUserName)

    ' Save
    oPerson.DataSource.Save
    Result = Result And CheckError("Save CDO User " & strUserName)

    'CleanUp
    Set oPerson = Nothing
    Set oMailbox = Nothing

    DeleteMailboxCDOPerson = Result
End Function

Example (ADSI)

[Visual Basic]
Sub Delete_MailBoxADSI(ServerName As String, _
                       DomainName As String, _
                       recipname As String)

'ServerName is something like "MyServer6"
'DomainName is something like "DC=MYDOMAIN3,DC=microsoft,DC=com"
'recipname is something like "jamessmith"

Dim objUser As IADsUser
Dim objMailbox As CDOEXM.IMailboxStore

Set objUser = GetObject("LDAP://" + ServerName + _
                        "/CN=" + recipname + _
                        ",CN=users," + DomainName)

Set objMailbox = objUser
If objMailbox.HomeMDB = "" Then
   MsgBox "No mailbox found."
Else
   objMailbox.DeleteMailbox
   objUser.SetInfo
   MsgBox "Mailbox for " + recipname + " deleted successfully"
End If

End Sub
© 2000-2001 Microsoft Corporation. All rights reserved.


MoveMailBox Method

This method moves a mailbox to a specified URL.

[Visual Basic,VBScript]
Sub MoveMailBox(HomeMDBURL As String)
[C++]
HRESULT MoveMailBox(BSTR HomeMDBURL);
[IDL]
HRESULT MoveMailBox([in] BSTR HomeMDBURL);
HomeMDBURL
The URL to the new mailbox location. This value can be saved as a standard e-mail name or as a DN value. See E-mail Addresses Stored as Active Directory Paths for more information.

Remarks

Example (CDO)

[Visual Basic]
Sub CDOMove_Mailbox(ServerName As String, _
                    DomainName As String, _
                    recipname As String, _
                    Moveto_MDB As String)

'ServerName is something like "MyServer6"
'DomainName is something like "DC=MYDOMAIN3,DC=microsoft,DC=com"
'recipname is is the e-mail alias (eg. "jamessmith)."
'This assumes you have created the MDB Moveto_MDB (with a name like "PrivateMDB2")

Dim objPerson As New CDO.Person
Dim objMailbox As CDOEXM.IMailboxStore

On Error GoTo Error

objPerson.DataSource.Open "LDAP://" + ServerName + _
                            "/CN=" + recipname + _
                            ",CN=users," + DomainName

Set objMailbox = objPerson
If objMailbox.HomeMDB = "" Then
   Debug.Print "No mailbox to move."
Else
  Debug.Print "Current MDB: " + objMailbox.HomeMDB
  'Moveto_MDB is the MDB name to move the mailbox to (eg. PrivateMDB2)

  objMailbox.MoveMailbox "LDAP://" + ServerName + "/CN=" + Moveto_MDB + _
                         ",CN=First Storage Group,CN=InformationStore,CN=" + _
                         ServerName + _
                         ",CN=Servers,CN=First Administrative Group," + _
                         "CN=Administrative Groups,CN=First Organization," + _
                         "CN=Microsoft Exchange,CN=Services,CN=Configuration," + _
                         DomainName
  objPerson.DataSource.Save
  Debug.Print "Mailbox has been moved to " + Moveto_MDB + " successfully."
End If
GoTo Ending

Error:
If Err.number = -2147016656 Then
   Debug.Print "Recipient " + recipname + " does not exist in the default container."
   MsgBox "Recipient " + recipname + " is not found."
   Err.Clear
Else
   MsgBox "Run time error: " + Str(Err.number) + " " + Err.Description
   Err.Clear
End If

Ending:
End Sub

Example (ADSI)

[Visual Basic]
Sub ADSIMove_Mailbox(ServerName As String, _
                     DomainName As String, _
                     recipname As String, _
                     Moveto_MDB As String)

'ServerName is something like "MyServer6"
'DomainName is something like "DC=MYDOMAIN3,DC=microsoft,DC=com"
'recipname is is the e-mail alias (eg. "jamessmith)."
'This assumes you have created the MDB Moveto_MDB (with a name like "PrivateMDB2")

Dim objUser As IADsUser
Dim objMailbox As CDOEXM.IMailboxStore

On Error GoTo Error

Set objUser = GetObject("LDAP://" + ServerName + _
                        "/CN=" + recipname + _
                        ",CN=users," + DomainName)

Set objMailbox = objUser
If objMailbox.HomeMDB = "" Then
   Debug.Print "No mailbox to move."
Else
  Debug.Print "Current MDB: " + objMailbox.HomeMDB

  'Moveto_MDB is the MDB name to move the mailbox to (eg. PrivateMDB2)

  objMailbox.MoveMailbox "LDAP://" + ServerName + "/CN=" + Moveto_MDB + _
                         ",CN=First Storage Group,CN=InformationStore,CN=" + _
                         ServerName + _
                         ",CN=Servers,CN=First Administrative Group," + _
                         "CN=Administrative Groups,CN=First Organization," + _
                         "CN=Microsoft Exchange,CN=Services,CN=Configuration," + _
                         DomainName

  objUser.SetInfo
  Debug.Print "Mailbox has been moved to " + Moveto_MDB + " successfully."
End If
GoTo Ending

Error:
If Err.number = -2147016656 Then
   Debug.Print "Recipient " + recipname + " does not exist in the default container."
   MsgBox "Recipient " + recipname + " is not found."
   Err.Clear
Else
   MsgBox "Run time error: " + Str(Err.number) + " " + Err.Description
   Err.Clear
End If

Ending:

End Sub
© 2000-2001 Microsoft Corporation. All rights reserved.


IMailboxStoreDB Interface

This interface provides access to mailboxes in Microsoft® Exchange 2000 mailbox stores.

IID
25150F45-5734-11D2-A593-00C04F990D8A
Extends
IDispatch

Member Summary

Properties

Name | Type | Description
DataSource (Read-Only) | IDataSource2 [C++,IDL] IDataSource2* | Returns the IDataSource2 interface on the object.
DaysBeforeDeletedMailboxCleanup | [Visual Basic,VBScript] Long [C++,IDL] Long | The number of days deleted mailboxes are retained in the database.
DaysBeforeGarbageCollection | [Visual Basic,VBScript] Long [C++,IDL] Long | The days before deleted items will be permanently deleted from the store.
DBPath (Read-Only) | [Visual Basic,VBScript] String [C++,IDL]BSTR | The path for the mailbox files.
Enabled | [Visual Basic,VBScript] Boolean [C++,IDL] VARIANT_BOOL | Indicates whether this store should be mounted at startup.
Fields (Read-Only) | [Visual Basic] ADODB.Fields [C++,IDL] Fields* | The object's Fields collection.
GarbageCollectOnlyAfterBackup | [Visual Basic,VBScript] Boolean [C++,IDL] VARIANT_BOOL | Boolean that indicates that items can be permanently deleted from the store only after they have been backed up.
HardLimit | [Visual Basic,VBScript] Long [C++,IDL] Long | The maximum mailbox size (in kilobytes) before sending and receiving e-mail is suspended.
Name | [Visual Basic,VBScript] String [C++,IDL]BSTR | The name of the mailbox.
OfflineAddressList | [Visual Basic,VBScript] String [C++,IDL]BSTR | The location of the offline address list for mailboxes on this database.
OverQuotaLimit | [Visual Basic,VBScript] Long [C++,IDL] Long | The maximum number of kilobytes over the StoreQuota before sending is suspended.
PublicStoreDB | [Visual Basic,VBScript] String [C++,IDL]BSTR | The default public store path for this mailbox.
SLVPath (Read-Only) | [Visual Basic,VBScript] String [C++,IDL]BSTR | The path for stream files.
Status | [Visual Basic,VBScript] CDOEXMStoreDBStatus [C++,IDL]CDOEXMStoreDBStatus | The current status for the mailbox.
StoreQuota (Read-Only) | [Visual Basic,VBScript] Long [C++,IDL] Long | The maximum size, in kilobytes, allowed for the mailbox.

Methods

Name | Description
Dismount | Dismount the mailbox.
GetInterface | Returns the specified dual interface on the object.
Mount | Mount the mailbox.
MoveDataFiles | Move and change the paths for data files.


DataSource Property

Returns the IDataSource2 interface on this object.

[Visual Basic]
Property DataSource as IDataSource2
read-only
[C++]
HRESULT get_DataSource(IDataSource2** pVal);
[IDL]
HRESULT [propget] DataSource([out,retval] IDataSource2** pVal);

Remarks

You can use the DataSource property to obtain the IDataSource2 interface on this object. This is equivalent to using QueryInterface in C++ or Set in Visual Basic®, or using the GetInterface method.


DaysBeforeDeletedMailboxCleanup Property

Gets or sets the number of days that deleted mailboxes are retained in the database.

[Visual Basic,VBScript]
Property DaysBeforeDeletedMailboxCleanup as Long
[C++]
HRESULT get_DaysBeforeDeletedMailboxCleanup(long* pVal);
HRESULT put_DaysBeforeDeletedMailboxCleanup(long Val);
[IDL]
HRESULT [propget] DaysBeforeDeletedMailboxCleanup([out,retval] long* pVal);
HRESULT [propput] DaysBeforeDeletedMailboxCleanup([in] long Val);

Remarks

The default value for this property is -1 (no limit).


DaysBeforeGarbageCollection Property

Gets or sets the days before deleted items (in the garbage) are permanently deleted from the server.

[Visual Basic,VBScript]
Property DaysBeforeGarbageCollection as Long
[C++]
HRESULT get_DaysBeforeGarbageCollection(long* pVal);
HRESULT put_DaysBeforeGarbageCollection(long Val);
[IDL]
HRESULT [propget] DaysBeforeGarbageCollection([out,retval] long* pVal);
HRESULT [propput] DaysBeforeGarbageCollection([in] long Val);

Remarks

The default value for this property is -1 (no collection).

See DaysBeforeDeletedMailboxCleanup for related information.


DBPath Property

The path for the mailbox.

[Visual Basic,VBScript]
Property DBPath as String
read-only
[C++]
HRESULT get_DBPath(BSTR* pVal);
[IDL]
HRESULT [propget] DBPath([out,retval] BSTR* pVal);


Enabled Property

Platform SDK: Exchange 2000 Server

Enabled

Indicates whether this store should be mounted at startup.

[Visual Basic,VBScript]
Property Enabled as Boolean
[C++]
HRESULT get_Enabled(VARIANT_BOOL* pVal);
HRESULT put_Enabled(VARIANT_BOOL pVal);
[IDL]
HRESULT [propget] Enabled([out,retval] VARIANT_BOOL* pVal);
HRESULT [propput] Enabled([in] VARIANT_BOOL pVal);

Remarks

When set to true, the store will be mounted at startup.


Fields Property

The Fields collection for the object.

[Visual Basic]
Property Fields as ADODB.Fields
read-only
[C++]
HRESULT get_Fields(Fields** pVal);
[IDL]
HRESULT [propget] Fields([out,retval] Fields** pVal);

Remarks

The Fields property obtains a collection of ADO Field objects, each of which contains a field relating to the MailboxStoreDB object.

Note When you use the ADO Fields.Update method, field values are updated only in memory. You must call IDataSource.Save to save the changes to the Web Storage System. To get the IDataSource interface, use the GetInterface method on the CDO object.


GarbageCollectOnlyAfterBackup Property

When enabled this prevents permanent deletion of items from the store unless they have been backed up.

[Visual Basic,VBScript]
Property GarbageCollectOnlyAfterBackup as Boolean
[C++]
HRESULT get_GarbageCollectOnlyAfterBackup(VARIANT_BOOL* pVal);
HRESULT put_GarbageCollectOnlyAfterBackup(VARIANT_BOOL pVal);
[IDL]
HRESULT [propget] GarbageCollectOnlyAfterBackup([out,retval] VARIANT_BOOL* pVal);
HRESULT [propput] GarbageCollectOnlyAfterBackup([in] VARIANT_BOOL pVal);

Remarks

When set to true, items in the store that have not been backed up cannot be permanently deleted.


HardLimit Property

This property specifies the maximum mailbox size, in kilobytes, over which sending and receiving mail is disabled.

[Visual Basic,VBScript]
Property HardLimit as Long
[C++]
HRESULT get_HardLimit(long* pVal);
HRESULT put_HardLimit(long Val);
[IDL]
HRESULT [propget] HardLimit([out,retval] long* pVal);
HRESULT [propput] HardLimit([in] long Val);

Remarks

If this value is 0, there is no specific limit to the mailbox size.

See StoreQuota and OverQuotaLimit for related information.

Note IMailboxStoreDB quota values apply to all mailboxes in the store. However, these values can be individually overridden in the IMailboxStore interface.

Example

See the IMailboxStore Hardlimit property.


Name Property

Returns or sets the name of the mailbox.

[Visual Basic,VBScript]
Property Name as String
[C++]
HRESULT get_Name(BSTR* pVal);
HRESULT put_Name(BSTR pVal);
[IDL]
HRESULT [propget] Name([out,retval] BSTR* pVal);
HRESULT [propput] Name([in] BSTR Val);


OfflineAddressList Property

The location of the offline address list for mailboxes on this database.

[Visual Basic,VBScript]
Property OfflineAddressList as String
[C++]
HRESULT get_OfflineAddressList(BSTR* pVal);
HRESULT put_OfflineAddressList(BSTR pVal);
[IDL]
HRESULT [propget] OfflineAddressList([out,retval] BSTR* pVal);
HRESULT [propput] OfflineAddressList([in] BSTR Val);

Remarks

The Exchange Administration Tool lets you define this offline address list in Active Directory™. This is an LDAP protocol link to that address.


OverQuotaLimit Property

The maximum number of kilobytes of a mailbox before sending messages is suspended.

[Visual Basic,VBScript]
Property OverQuotaLimit as Long
[C++]
HRESULT get_OverQuotaLimit(long* pVal);
HRESULT put_OverQuotaLimit(long Val);
[IDL]
HRESULT [propget] OverQuotaLimit([out,retval] long* pVal);
HRESULT [propput] OverQuotaLimit([in] long Val);

Remarks

See StoreQuota and HardLimit for related information.

Note IMailboxStoreDB quota values apply to all mailboxes in the store. However these values can be individually overridden in the IMailboxStore interface


PublicStoreDB Property

The default public store path.

[Visual Basic,VBScript]
Property PublicStoreDB as String
[C++]
HRESULT get_PublicStoreDB(BSTR* pVal);
HRESULT put_PublicStoreDB(BSTR pVal);
[IDL]
HRESULT [propget] PublicStoreDB([out,retval] BSTR* pVal);
HRESULT [propput] PublicStoreDB([in] BSTR Val);


SLVPath Property

The path for stream files.

[Visual Basic,VBScript]
Property SLVPath as String
read-only
[C++]
HRESULT get_SLVPath(BSTR* pVal);
[IDL]
HRESULT [propget] SLVPath([out,retval] BSTR* pVal);


Status Property

Gets the status for this mailbox.

[Visual Basic]
Property Status as CDOEXMStoreDBStatus
(read-only)
[C++]
HRESULT get_Status(CDOEXMStoreDBStatus* pVal);
[IDL]
HRESULT [propget] Status([out,retval] CDOEXMStoreDBStatus* pVal);

Remarks

The CDOEXMStoreDBStatus enumeration is provided for this property. The status can indicate if the mailbox is online, offline, mounting, or dismounting.


StoreQuota Property

This property specifies the maximum size, in kilobytes, allowed for mailboxes.

[Visual Basic,VBScript]
Property StoreQuota as Long
[C++]
HRESULT get_StoreQuota(long* pVal);
HRESULT put_StoreQuota(long Val);
[IDL]
HRESULT [propget] StoreQuota([out,retval] long* pVal);
HRESULT [propput] StoreQuota([in] long Val);

Remarks

If this value is 0, there is no limit to the mailbox size.

Above this limit the recipient will get a warning.

See StoreQuota and OverQuotaLimit for related information.

Note IMailboxStoreDB quota values apply to all mailboxes in the store. However, these values can be individually overridden in the IMailboxStore interface.


Dismount Method

Dismount this mailbox store.

[Visual Basic,VBScript]
Function Dismount(Optional Timeout as Long)
[C++]
HRESULT Dismount(long Timeout);
[IDL]
HRESULT Dismount([in,optional] long Timeout);
Timeout
The time in seconds to attempt dismounting.

Remarks

The default value for Timeout is -1 (no time-out).

The mailbox store can be dismounted even if the mailbox is enabled. However, if the server is restarted, the mailbox will automatically be mounted again.


GetInterface Method

Returns the specified dual interface on the object.

[Visual Basic]
Function GetInterface(ByVal Interface as String) as Object
[C++]
HRESULT GetInterface(BSTR Interface, IDispatch** pVal);
[IDL]
HRESULT GetInterface([in] BSTR Interface, [out,retval] IDispatch** pVal);
Interface
The name of the interface to obtain.

Remarks

The GetInterface method is primarily intended as a generic interface navigation aid to scripting languages that do not support such navigation directly. Most COM classes that provide implementations of the IMessage interface expose additional dual interfaces that are accessible by scripting languages only through properties on the interface, such as BodyPart and DataSource, or through the GetInterface method. When properties do not exist on the interface to return these interfaces, the GetInterface method must be used.

The list of valid interface names to pass to GetInterface is dependent upon a specific implementation. As a general rule, the name of the desired interface should match the physical name of the interface as it appears in the type library or .idl file. Check the appropriate COM class for a list of exposed dual interfaces.

Example

The following example in Visual Basic Scripting Edition (VBScript) demonstrates using GetInterface to return other interfaces on a MailboxStoreDB object.

[VBScript]
Dim istoredb as IMailboxStoreDB
Dim idsrc as IDataSource2

'Create an instance and get IMailboxStoreDB (IDispatch) back
Set istoredb = CreateObject("CDOEXM.MailboxStoreDB")

'Get IDataSource2 on the MailboxStoreDB Object
Set idsrc = istoredb.GetInterface("IDataSource2")
[JScript]
var istoredb = new ActiveXObject("CDOEXM.MailboxStoreDB");
var iDsrc = istoredb.GetInterface("IDataSource2");


Mount Method

Mount this mailbox store.

[Visual Basic,VBScript]
Function Mount(Optional Timeout as Long)
[C++]
HRESULT Mount(long Timeout);
[IDL]
HRESULT Mount([in,optional] long Timeout);
Timeout
The time in seconds to attempt dismounting.

Remarks

The default value for Timeout is -1 (no time-out).

You will need to mount the mailbox store if it has been dismounted, newly created, or re-enabled. To mount the mailbox store the server must be running and the mailbox must be enabled.


MoveDataFiles Method

Relocates files to different paths and sets the path locations for new files.

[Visual Basic,VBScript]
Function MoveDataFiles(DBPath As String,
                       SLVPath As String,
                       Optional Flags as Long)
[C++]
HRESULT MoveDataFiles(BSTR DBPath,
                      BSTR SLVPath,
                      long Flags);
[IDL]
HRESULT MoveDataFiles([in] BSTR DBPath,
                      [in] BSTR SLVPath,
                      [in,optional] long Flags);
DBPath
The new path for the mailbox MDB.
SLVPath
The new path for the SLV (stream) files.
Flags
Reserved for future use.

Remarks

When you move the files, the specified paths become the paths for new files.

Note You must Dismount the mailbox store before moving mailbox files.


IMailRecipient Interface

Provides properties to support mail to and from contacts. See Managing Mail Recipients for overview information.

IID
25150F40-5734-11d2-A593-00C04F990D8A
Extends
IDispatch

Member Summary

Properties

Name | Type | Description
AutoGenerateEmailAddresses | [Visual Basic,VBScript] Boolean [C++,IDL] VARIANT_BOOL | Indicates whether the Recipient Update Service will update the recipient e-mail addresses.
Alias | [Visual Basic,VBScript] String [C++,IDL] BSTR | The e-mail alias of the recipient.
ForwardingStyle | [Visual Basic,VBScript] CDOEXMDeliverAndRedirect [C++,IDL] CDOEXMDeliverAndRedirect | Indicates whether mail is also delivered to an alternative e-mail address.
ForwardTo | [Visual Basic,VBScript] String [C++,IDL] BSTR | The mailbox recipient to which mail is forwarded.
HideFromAddressBook | [Visual Basic,VBScript] Boolean [C++,IDL] VARIANT_BOOL | Indicates whether the address is displayed in the address book.
IncomingLimit | [Visual Basic,VBScript] Long [C++,IDL] long | The maximum size, in kilobytes, of a message sent to the recipient.
OutgoingLimit | [Visual Basic,VBScript] Long [C++,IDL] long | The maximum size, in kilobytes, of a message sent from the recipient.
ProxyAddresses | [Visual Basic,VBScript] Variant [C++,IDL] VARIANT | A list of proxy addresses for the recipient.
RestrictedAddresses | [Visual Basic,VBScript] CDORestrictedAddressType [C++,IDL] CDORestrictedAddressType * | Defines the meaning of RestrictedAddressList.
RestrictedAddressList | [Visual Basic,VBScript] Variant [C++,IDL] VARIANT | A list of addresses to accept or reject.
SMTPEmail | [Visual Basic,VBScript] String [C++,IDL] BSTR | The SMTP address used for the recipient.
TargetAddress (Read-only) | [Visual Basic,VBScript] String [C++,IDL] BSTR | The foreign mail system address to which the mail for this recipient should be sent.
X400Email | [Visual Basic,VBScript] String [C++,IDL] BSTR | The X.400 address used for the recipient.

Methods

Name | Description
MailDisable | Disable mail to a custom recipient.
MailEnable | Enable mail to a custom recipient.


AutoGenerateEmailAddresses Property

This property specifies whether the Recipient Update Service updates the recipient e-mail delivery proxy addresses.

[Visual Basic,VBScript]
Public Property AutoGenerateEmailAddresses as Boolean
[C++]
HRESULT get_AutoGenerateEmailAddresses(VARIANT_BOOL* pVal);
HRESULT put_AutoGenerateEmailAddresses(VARIANT_BOOLVal);
[IDL]
HRESULT [propget] AutoGenerateEmailAddresses([out,retval] VARIANT_BOOL* pVal);
HRESULT [propput] AutoGenerateEmailAddresses([in] VARIANT_BOOL Val);

Remarks

If this property is true, e-mail delivery proxy addresses for the recipient will be updated as needed by the Exchange Recipient Update Service, overriding any changes made to the recipient proxy addresses. Set this property to false to prevent the Recipient Update Service from changing the values. This is useful when it is necessary to manually specify the proxy addresses.


Alias Property

The e-mail alias of the recipient.

[Visual Basic,VBScript]
Public Property Alias as String
[C++]
HRESULT get_Alias (BSTR* pVal);
HRESULT put_Alias (BSTR Val);
[IDL]
HRESULT [propget] Alias ([out,retval] BSTR* pVal);
HRESULT [propput] Alias ([in] BSTR Val);

Remarks

The default value for this property is NULL (no alias specified).

Example

Someone is the alias for Some One with an e-mail address of someone@microsoft.com.


ForwardingStyle Property

This property specifies whether mail is also delivered to an alternative mail address.

[Visual Basic,VBScript]
Property ForwardingStyle as CDOEXMDeliverAndRedirect
[C++]
HRESULT get_ForwardingStyle (CDOEXMDeliverAndRedirect* pVal);
HRESULT put_ForwardingStyle (CDOEXMDeliverAndRedirectVal);
[IDL]
HRESULT [propget] ForwardingStyle ([out,retval] CDOEXMDeliverAndRedirect* pVal);
HRESULT [propput] ForwardingStyle ([in] CDOEXMDeliverAndRedirectVal);
CDOEXMDeliverAndRedirect
Enumerated type to specify how forwarding is enabled.

Remarks

See the CDOEXMDeliverAndRedirect enumeration.


ForwardTo Property

This property specifies the URL where mail is to be forwarded.

[Visual Basic,VBScript]
Public Property ForwardTo as String
[C++]
HRESULT get_ForwardTo(BSTR* pVal);
HRESULT put_ForwardTo(BSTR Val);
[IDL]
HRESULT [propget] ForwardTo([out,retval] BSTR* pVal);
HRESULT [propput] ForwardTo([in] BSTR Val);

Remarks

This property is a URL to the mailbox recipient or mail-enabled recipient (such as a contact/distribution list/public folder object) to whom mail is forwarded. The default value for this property is NULL.

Whether mail is always forwarded to an alternative address or forwarded only when it cannot be delivered to the recipient depends on the value of the ForwardingStyle property.

This property accepts both e-mail addresses and the Microsoft® Windows® Active Directory™ paths, yet in either case the addresses are converted to Active Directory paths. See E-mail Addresses Stored as Active Directory Paths for more information.


HideFromAddressBook Property

This property specifies whether the address is displayed in the address book.

[Visual Basic,VBScript]
Public Property HideFromAddressBook as Boolean
[C++]
HRESULT get_HideFromAddressBook(VARIANT_BOOL* pVal);
HRESULT put_HideFromAddressBook(VARIANT_BOOLVal);
[IDL]
HRESULT [propget] HideFromAddressBook([out,retval] VARIANT_BOOL* pVal);
HRESULT [propput] HideFromAddressBook([in] VARIANT_BOOL Val);

Remarks

If this property is true, the address is not displayed in the address book; if this property is false, the address is displayed in the address book. By default, this property is false (display address in address book).


IncomingLimit Property

This property specifies the maximum size, in kilobytes, of a message sent to the recipient.

[Visual Basic,VBScript]
Public Property IncomingLimit as Long
[C++]
HRESULT get_IncomingLimit(Long* pVal);
HRESULT put_IncomingLimit(Long Val);
[IDL]
HRESULT [propget] IncomingLimit([out,retval] Long* pVal);
HRESULT [propput] IncomingLimit([in] Long Val);

Remarks

The default value is -1, which indicates no limit.


OutgoingLimit Property

This property specifies the maximum size, in kilobytes, of a message sent from the recipient.

[Visual Basic,VBScript]
Public Property OutgoingLimit as Long
[C++]
HRESULT get_OutgoingLimit(Long* pVal);
HRESULT put_OutgoingLimit(Long Val);
[IDL]
HRESULT [propget] OutgoingLimit([out,retval] Long* pVal);
HRESULT [propput] OutgoingLimit([in] Long Val);

Remarks

The default value is -1, which indicates no limit.


ProxyAddresses Property

This property is a list of proxy addresses for the recipient.

[Visual Basic,VBScript]
Public Property ProxyAddresses as Variant
[C++]
HRESULT get_ProxyAddresses(VARIANT* Val));
HRESULT put_ProxyAddresses(VARIANT Val));
[IDL]
HRESULT [propget] ProxyAddresses([out,retval] VARIANT* Val));
HRESULT [propput] ProxyAddresses([in] VARIANT Val));

Remarks

The default value for this property is NULL (no proxy addresses defined).

This list can contain all types of proxies. The proxies must be prefixed by the proxy type (for example, “smtp:”, “x400:”).

Denote the primary reply address by putting it in all caps. Thus the following specifies proxy2 as the primary reply address, and thereby specifies the others as receive only.

smtp:proxy1@somewhere.microsoft.com

SMTP:proxy2@somewhere.microsoft.com

x400:c=us;a= ;p=Domain;o=First Organization;s=Surname;g=Name;

EXAMPLE

[Visual Basic]
Sub SetProxyAddress(ServerName As String, _
                    DomainName As String, _
                    recipname As String)

    'ServerName is something like "MyServer6"
    'DomainName is something like "DC=MYDOMAIN3,DC=microsoft,DC=com"
    'recipname is something like "jamessmith"

    Dim objPerson As New CDO.Person
    Dim objMailRecip As CDOEXM.IMailRecipient
    Dim i

    objPerson.DataSource.Open "LDAP://" + ServerName + _
                              "/CN=" + recipname + _
                              ",CN=users," + DomainName

    'Capitalized proxy type for proxies(1) makes it the primary (reply) address.
    'the others are recieve only.
    Dim proxies(3) As Variant
    proxies(0) = "smtp:user@somewhere.microsoft.com"
    proxies(1) = "SMTP:user@somewhere.microsoft.com"
    proxies(2) = "x400:c=us;a= ;p=Domain;o=First Organization;s=user;"

    Set objMailRecip = objPerson
    objMailRecip.ProxyAddresses = proxies

    'look at the results
    Debug.Print Chr(13) + Chr(13) + Chr(13) + Chr(13) + Chr(13) 'add some space
    For i = LBound(objMailRecip.ProxyAddresses) To UBound(objMailRecip.ProxyAddresses)
      Debug.Print objMailRecip.ProxyAddresses(i)
    Next

    objPerson.DataSource.Save
    MsgBox "Proxy addresses for " + recipname + " set successfully"

End Sub
© 2000-2001 Microsoft Corporation. All rights reserved.


RestrictedAddresses Property

This property specifies what RestrictedAddressList means.

[Visual Basic,VBScript]
Public Property RestrictedAddresses as CDORestrictedAddressType
[C++]
HRESULT get_RestrictedAddresses(CDORestrictedAddressType* pVal);
HRESULT put_RestrictedAddresses(CDORestrictedAddressType Val);
[IDL]
HRESULT [propget] RestrictedAddresses([out,retval] CDORestrictedAddressType* pVal);
HRESULT [propput] RestrictedAddresses([in] CDORestrictedAddressType Val);
CDORestrictedAddressType
Defines whether the list contains addresses which are to be exclusively accepted, or rejected.

Remarks

See CDOEXMRestrictedAddressType for this enumeration definition.

If the list is blank, no inclusions or exclusions are performed.

Example

See RestrictedAddressList

© 2000-2001 Microsoft Corporation. All rights reserved.


RestrictedAddressList Property

This property specifies a list of recipients and groups to accept or reject.

[Visual Basic,VBScript]
Public Property RestrictedAddressList as Variant
[C++]
HRESULT get_RestrictedAddressList(VARIANT* Val));
HRESULT put_RestrictedAddressList(VARIANT Val));
[IDL]
HRESULT [propget] RestrictedAddressList([out,retval] VARIANT* Val));
HRESULT [propput] RestrictedAddressList([in] VARIANT Val));

Remarks

The default value for this property is NULL (no addresses defined).

This property is stored, encoded, in the protocol-settings multi-valued string attribute of the mail-recipient class.

If an e-mail address is not found as belonging to a recipient in Active Directory, the value is invalid. Thus this property is useful only for restricting or accepting addresses that can be resolved in Active Directory.

This property accepts both e-mail addresses and Windows Active Directory paths, yet in either case the addresses are converted to Active Directory paths. See E-mail Addresses Stored as Active Directory Paths for more information.

Example

Note This example uses a file URL with the Exchange OLE DB (ExOLEDB) provider. The ExOLEDB provider also supports the HTTP URL scheme.

[Visual Basic]
Sub RestrictAddresses(DomainName As String, _
                      FolderName As String)

    'DomainName is something like "MyDomain.wherever.com"
    'FolderName is something like "Public Folders/Folder3"

    Dim objFolder As New CDO.Folder
    Dim objMailRecip As CDOEXM.IMailRecipient
    Dim fullurl As String
    Dim i

    'fullurl might look like:
    ' "file://./backofficestorage/MyDomain.wherever.com/Public Folders/Folder3"
    fullurl = "file://./backofficestorage/" + _
              DomainName + "/" + FolderName

    objFolder.DataSource.Open fullurl, , adModeReadWrite, adFailIfNotExists

    Set objMailRecip = objFolder

    ' can build an accept or reject list
    objMailRecip.restrictedAddresses = cdoReject 'reject these emails

    Dim list(3) As Variant

    list(0) = "user@" + DomainName
    list(1) = "user1@" + DomainName
    list(2) = "user2@" + DomainName

    objMailRecip.RestrictedAddressList = list
    objFolder.DataSource.Save

    'look at the results
    Debug.Print Chr(13) + Chr(13) + "View list"
    For i = LBound(objMailRecip.RestrictedAddressList) To UBound(objMailRecip.RestrictedAddressList)
      Debug.Print objMailRecip.RestrictedAddressList(i)
    Next

    MsgBox "Mailbox restrictions for " + FolderName + " set successfully"

End Sub
© 2000-2001 Microsoft Corporation. All rights reserved.


SMTPEmail Property

This property specifies the primary SMTP address used for the recipient.

[Visual Basic,VBScript]
Public Property SMTPEmail as String
[C++]
HRESULT get_SMTPEmail (BSTR* pVal);
HRESULT put_SMTPEmail (BSTR Val);
[IDL]
HRESULT [propget] SMTPEmail ([out,retval] BSTR* pVal);
HRESULT [propput] SMTPEmail ([in] BSTR Val);

Remarks

The default value for this property is NULL (no address specified).

Example

jamessmith@somewhere.microsoft.com


TargetAddress Property

The address to which mail is redirected when mail is sent to this recipient.

[Visual Basic,VBScript]
Public Property TargetAddress as String
read-only
[C++]
HRESULT get_TargetAddress (BSTR* pVal);
[IDL]
HRESULT [propget] TargetAddress ([out,retval] BSTR* pVal);

Remarks

This property is read-only.

The default value for this property is NULL (no address specified).

This is set using the MailEnable and MailDisable methods.

This property is stored as an Active Directory path. See E-mail Addresses Stored as Active Directory Paths for more information.


X400Email Property

This property specifies the primary X.400 address used for the recipient.

[Visual Basic,VBScript]
Public Property X400Email as String
[C++]
HRESULT get_X400Email (BSTR* pVal);
HRESULT put_X400Email (BSTR Val);
[IDL]
HRESULT [propget] X400Email ([out,retval] BSTR* pVal);
HRESULT [propput] X400Email ([in] BSTR Val);

Remarks

The default value for this property is NULL (no address specified).


MailDisable Method

This method disables mail to a recipient. The recipient can be a user, folder, contact or group.

[Visual Basic,VBScript]
Subroutine MailDisable()
[C++]
HRESULT MailDisable();
[IDL]
HRESULT MailDisable();

Remarks

The MailDisable method clears all the proxy addresses, ProxyAddresses property, (including SMTPEMail, X400Email properties) and the TargetAddress property.

Example (CDO)

[Visual Basic]
Function MailDisableCDOPerson(strFirstName As String, _
                                 strLastName As String) As Boolean

    Dim oPerson         As New CDO.Person
    Dim oRecipient      As CDOEXM.IMailRecipient
    Dim strUserName     As String
    Dim strConatinerName As String
    Dim strURL          As String
    Dim Result       As Boolean

    Result = True

    strUserName = strFirstName & strLastName

    strContainerName = "Users"
    ' Create URL for the user
    Result = Result And CreateUserURL(strURL, strContainerName, False, strUserName)

    Set oPerson = New CDO.Person
    ' Bind
    oPerson.DataSource.Open strURL
    Result = Result And CheckError("Bind to CDO User " & strUserName)

    ' MailDisable
    Set oRecipient = oPerson
    oRecipient.MailDisable
    Result = Result And CheckError("Mail Disablee CDO User " & strUserName)

    ' Save
    oPerson.DataSource.Save
    Result = Result And CheckError("Save CDO User " & strUserName)

    'CleanUp
    Set oPerson = Nothing
    Set oRecipient = Nothing

    MailDisableCDOPerson = Result
End Function
© 2000-2001 Microsoft Corporation. All rights reserved.


MailEnable Method

This method enables mail to a recipient. The recipient can be a user, folder, contact or group.

[Visual Basic,VBScript]
Subroutine MailEnable(Optional ByVal TargetMailAddress as String)
[C++]
HRESULT MailEnable(BSTR TargetMailAddress );
[IDL]
HRESULT MailEnable([in,optional] BSTR TargetMailAddress);
TargetMailAddress
The TargetMailAddress sets the ImailRecipient:TargetAddress property.

Remarks

The MailEnable method creates the proxy addresses (sets the ProxyAddresses property, and the SMTPEMail and X400Email properties).

MailEnable also sets the TargetAddress property if the object type is not a group. When MailEnable method is called with a TargetMailAddress parameter (for a recipient or a contact), it sets the TargetAddress property.

Example (CDO)

[Visual Basic]
Function MailEnableCDOPerson(strFirstName As String, _
                             strLastName As String, _
                             strTargetMailAddress As String) As Boolean

    Dim oPerson             As New CDO.Person
    Dim oRecipient          As CDOEXM.IMailRecipient
    Dim strUserName         As String
    Dim strURL              As String
    Dim strContainerName    As String
    Dim Result              As Boolean
    Dim forward_email       As String

    Result = True
    'Target address should look like this
    'strTargetMailAddress = strLastName & "@somewhere.com"

    strUserName = strFirstName & strLastName
    strContainerName = "Users"
    ' Create URL for the user
    Result = Result And CreateUserURL(strURL, strContainerName, False, strUserName)

    oPerson.FirstName = strFirstName
    oPerson.LastName = strLastName

    oPerson.DataSource.SaveTo strURL
    Result = Result And CheckError("SaveTo " & strURL)

    Set oPerson = New CDO.Person

    ' Bind
    oPerson.DataSource.Open strURL
    Result = Result And CheckError("Bind to CDO User " & strUserName)

    ' MailEnable
    Set oRecipient = oPerson
    oRecipient.MailEnable strTargetMailAddress
    Result = Result And CheckError("Mail Enable CDO User " & strUserName)

    If oRecipient.TargetAddress = "" And oRecipient.X400Email = "" Then
       forward_email = "smtp:" + recipname + "@" + forward_domain
       oRecipient.MailEnable forward_email  'where to forward the mail to
       oRecipient.IncomingLimit = 50
       oRecipient.OutgoingLimit = 50
       ' Save
       oPerson.DataSource.Save
       Result = Result And CheckError("Save CDO User " & strUserName)

       MsgBox recipname + " mail enabled successfully"
    Else
       MsgBox recipname + " is already mail enabled"
    End If

    'CleanUp
    Set oPerson = Nothing
    Set oRecipient = Nothing

    MailEnableCDOPerson = Result
End Function
© 2000-2001 Microsoft Corporation. All rights reserved.


IMember Interface

Returned by the IMembers.Item property and used to access information about a security principal.

IID
CD001026-8B95-11D1-82DB-00C04FB1625D
Extends
IDispatch

Member Summary

Properties

Name | Type | Description
Name | [Visual Basic,VBScript] String [C++,IDL] String | Returns the member's name. Either a user principal name (UPN) or the Web Storage System role name.
Type | [Visual Basic,VBScript] MemberType [C++,IDL] MemberType* | Identifies the name type as e-mail address or folder role.


Name Property

Returns the member's name.

[Visual Basic,VBScript]
Property Name As String
[C++]
HRESULT get_Name( BSTR* pbsName);
[IDL]
HRESULT Name([out, retval] BSTR* pbsName);

Remarks

Use this name to index members of the ItemAuthors and ItemReaders collections.

Example

Name | Type
"someone@microsoft.com" | cdowfEmailAddress (0)
"Role1" ... "Role16" | cdowfRole (1)

See Also

CdoWfMemberType Enum

IWorkflowSession.ItemAuthors

IWorkflowSession.ItemReaders

IMembers Interface

Using the WorkflowSession Object

© 2000-2001 Microsoft Corporation. All rights reserved.


Type Property

Identifies the name type as UPN or the Web Storage System folder role.

[Visual Basic,VBScript]
Property Type As MemberType
[C++]
HRESULT get_Type( MemberType* varType);
[IDL]
HRESULT Type([out, retval] MemberType* varType);

Remarks

Use this property to specify what type of name you are using in the IMember Name property. You can get e-mail addresses from the IWorkflowSession Sender property and from Active Directory using IWorkflowSession.GetUserProperty method.

A folder role is a grouping of one or more Active Directory security identifiers (SID) into a SID that is stored as a property on a folder. The folder role only exists on the folder and not in Active Directory. You can determine if a user is in a given folder role using the WorkflowSession object IsUserInRole method. There are sixteen valid folder role names that you can use. The valid names that you can use with IsUserInRole method are "Role1" through "Role16".

Example

Name | Type
"someone@microsoft.com" | cdowfEmailAddress (0)
"Role1" ... "Role16" | cdowfRole (1)

See Also

CdoWfMemberType Enum

IWorkflowSession.ItemAuthors

IWorkflowSession.ItemReaders

IMembers Interface

Using the WorkflowSession Object

© 2000-2001 Microsoft Corporation. All rights reserved.


IMembers Interface

A collection of security principals returned by ItemAuthors and ItemReaders properties.

IID

CD001027-8B95-11D1-82DB-00C04FB1625D

Extends
IDispatch

Member Summary

Properties

Name | Type | Description
Count | [Visual Basic,VBScript] Long [C++,IDL] Long | Returns the number of members in the collection.
Item | [Visual Basic,VBScript] IMember [C++,IDL] IMember* | Provides access to an individual member of the collection.

Methods

Name |
Add | Adds a new member to the collection.
Clear | Removes all members of the collection.
Delete | Removes an individual member of the collection.


Count Property

Returns the number of members in the collection.

[Visual Basic,VBScript]
Property Count As Long
[C++]
HRESULT Count( long* varCount);
[IDL]
HRESULT Count([out, retval] long* varCount);

Example

This example uses the count property to get the number of members in the IWorkflowSession interface, ItemReaders collection. You can also use this with the ItemAuthors collection.

[VBScript]
mbrCount = WorkflowSession.ItemReaders.Count

See Also

ItemReaders

ItemAuthors

IMember

© 2000-2001 Microsoft Corporation. All rights reserved.


Item Property

Provides access to an individual member of the collection.

[Visual Basic,VBScript]
Property Item(varIndex) As IMember
[C++]
HRESULT Item(
                VARIANT varIndex,
                IMember** ppMember);
[IDL]
HRESULT Item(
                [in] VARIANT varIndex,
                [out, retval] IMember** ppMember);

Remarks

varIndex is a string or one-based ordinal number. If it is a string, it represents either an e-mail address or a folder role. E-mail addresses must be in the form someone@microsoft.com. Valid role identifiers include "Role1", "Role2", ... , "Role16". This is the default property of the IMembers collection so you do not have to reference it explicitly when using the IMembers collection (ItemAuthors or ItemReaders).

Example

This example uses the Item property to determine if the e-mail address is a member of the IWorkflowSession interface, ItemAuthors collection. If the e-mail address is a member of the ItemAuthors collection, the script gives that member exclusive read access to the workflow item.

[VBScript]
emAddress = "someone@microsoft.com"
if not (WorkflowSession.ItemAuthors(emAddress) is nothing) then
   WorkflowSession.ItemReaders.Clear
   WorkflowSession.ItemReaders.Add emAddress
end if

See Also

ItemReaders

ItemAuthors

IMember

© 2000-2001 Microsoft Corporation. All rights reserved.


Add Method

Adds a new member to the collection.

[Visual Basic,VBScript]
Sub Add(bsName As String, Type As MemberType)
[C++]
HRESULT Add(
                BSTR bsName,
                MemberType Type);
[IDL]
HRESULT Add(
                [in] BSTR bsName,
                [in] MemberType Type);

Remarks

The name you add must be one of the following two types.

Name | Type
"someone@microsoft.com" | cdowfEmailAddress (0)
"Role1" ... "Role16" | cdowfRole (1)

While someone@microsoft.com is a fictitious name, "Role1" through "Role16" are literal names and are the only ones valid for type cdowfRole. The Add method has different effects depending on which collection you are adding members to.

Collection | Effect of Add method
ItemAuthors | Extends or adds to the folder default. Any members you add are in addition to those allowed to modify and delete items by folder default role.
ItemReaders | Replaces the folder default. Only those members you add are allowed access to the item. If ItemReaders has no members, the folder default applies.

Example

This example adds a user to the IWorkflowSession interface, ItemAuthors collection.

[VBScript]
emAddress = "someone@microsoft.com"
WorkflowSession.ItemAuthors.Add emAddress, 0 'cdowfEmailAddress

See Also

ItemReaders

ItemAuthors

IMember

© 2000-2001 Microsoft Corporation. All rights reserved.


Clear Method

Removes all members of the collection.

[Visual Basic,VBScript]
Sub Clear()
[C++]
HRESULT Clear();
[IDL]
HRESULT Clear();

Remarks

This method takes no arguments.

Example

This example removes all members of the IWorkflowSession interface, ItemReaders collection.

[VBScript]
WorkflowSession.ItemReaders.Clear

See Also

ItemReaders

ItemAuthors

IMember

© 2000-2001 Microsoft Corporation. All rights reserved.


Delete Method

Removes an individual member of the collection.

[Visual Basic,VBScript]
Sub Delete(varIndex)
[C++]
HRESULT Delete( VARIANT varIndex);
[IDL]
HRESULT Delete([in] VARIANT varIndex);

Remarks

varIndex can be a string or one-based ordinal number. If varIndex is a string, it must be one of the following two types.

Name | Type
"someone@microsoft.com" | cdowfEmailAddress (0)
"Role1" ... "Role16" | cdowfRole (1)

While someone@microsoft.com is a fictitious name, "Role1" through "Role16" are literal names and are the only ones valid for type cdowfRole.

Example

This example removes the user specified by emAddress from the IWorkflowSession interface, ItemAuthors collection.

[VBScript]
emAddress = "someone@microsoft.com"
WorkflowSession.ItemAuthors.Delete emAddress

See Also

ItemReaders

ItemAuthors

IMember

© 2000-2001 Microsoft Corporation. All rights reserved.


IMessage Interface

The IMessage interface defines methods and properties used to manage messages.

IID
CD000020-8B95-11D1-82DB-00C04FB1625D
Extends
IDispatch

Member Summary

Properties

Name | Type | Description
Attachments (Read-Only) | [Visual Basic] IBodyParts [C++,IDL] IBodyParts* | The collection of attachments for this message.
AutoGenerateTextBody | [Visual Basic] Boolean [C++,IDL] VARIANT_BOOL | Indicates whether the TextBody of a message should automatically be generated from the contents of the HTMLBody property for a multipart/alternative message.
BCC | [Visual Basic] String [C++,IDL] BSTR | The blind carbon copy (Bcc) recipients for this message.
BodyPart (Read-Only) | [Visual Basic] IBodyPart [C++,IDL] IBodyPart* | The IBodyPart interface on this object.
CC | [Visual Basic] String [C++,IDL] BSTR | The informational (carbon copy, or Cc) recipients for this message.
Configuration | [Visual Basic] IConfiguration [C++,IDL] IConfiguration | The Configuration object for the message.
DataSource (Read-Only) | IDataSource [C++,IDL] IDataSource* | The IDataSource interface on the object.
DSNOptions | [Visual Basic] CdoDSNOptions [C++,IDL] CdoDSNOptions | The Delivery Status Notification (DSN) options for the message. These options include in the message a request for a return report on the delivery status of the message.
EnvelopeFields (Read-Only) | [Visual Basic] ADODB.Fields [C++,IDL] Fields* | A collection of fields associated with the SMTP or NNTP transport envelope of the message.
Fields (Read-Only) | [Visual Basic] ADODB.Fields [C++,IDL] Fields* | The object's Fields collection.
FollowUpTo | [Visual Basic] String [C++,IDL] BSTR | The newsgroups to which any responses to this message should be posted.
From | [Visual Basic] String [C++,IDL] BSTR | The address of the principal author of this message.
HTMLBody | [Visual Basic] String [C++,IDL] BSTR | The HTML representation of the body of this message.
HTMLBodyPart (Read-Only) | [Visual Basic] IBodyPart [C++,IDL] IBodyPart* | The BodyPart object in which the HTML content of this message is stored.
Keywords | [Visual Basic] String [C++,IDL] BSTR | A list of keywords assigned to this message.
MDNRequested | [Visual Basic] Boolean [C++,IDL] VARIANT_BOOL | Indicates whether a Message Disposition Notification (MDN) report is requested for the message.
MimeFormatted | [Visual Basic] Boolean [C++,IDL] VARIANT_BOOL | Indicates whether the message is to be formatted using Multipurpose Internet Mail Extensions (MIME).
Newsgroups | [Visual Basic] String [C++,IDL] BSTR | The newsgroup recipients of the message.
Organization | [Visual Basic] String [C++,IDL] BSTR | A description of the organization to which the sender belongs.
ReceivedTime (Read-Only) | [Visual Basic] Date [C++,IDL] DATE | The date/time this message was delivered to the server.
ReplyTo | [Visual Basic] String [C++,IDL] BSTR | The messaging address to which replies to this message should be sent.
Sender | [Visual Basic] String [C++,IDL] BSTR | The messaging address of the submitter of this message.
SentOn (Read-Only) | [Visual Basic] Date [C++,IDL] DATE | The date/time this message was submitted to the server.
Subject | [Visual Basic] String [C++,IDL] BSTR | The subject of this message.
TextBody | [Visual Basic] String [C++,IDL] BSTR | The plain text representation of the body of this message.
TextBodyPart (Read-Only) | [Visual Basic] IBodyPart [C++,IDL] IBodyPart* | The BodyPart object in which the text content of this message is stored.
To | [Visual Basic] String [C++,IDL] BSTR | The principal (To) recipients for this message.

Methods

Name | Description
AddAttachment | Adds an attachment to this message.
AddRelatedBodyPart | Adds an MHTML, HTML related to MIME, related body part to the message's content.
CreateMHTMLBody | Converts the contents of an entire Web page into MHTML-formatted body parts on this message.
Forward | Creates and returns another message that can be used to forward this message.
GetInterface | Returns the specified dual interface on the object.
GetStream | Returns the Stream object containing the complete message, including headers and all content, in serialized (wire-transport) format.
Post | Submits this message to the specified newsgroups.
PostReply | Creates and returns another message that can be used to post a reply to this message.
Reply | Creates and returns another message that can be used to reply to the sender of this message.
ReplyAll | Creates and returns another message that can be used to reply to the sender and all recipients.
Send | Sends the message.

Remarks

The IMessage interface defines methods and properties used by implementing objects to provide messaging functionality. COM classes that provide an implementation of the IMessage interface should allow you to:

  • Address messages and otherwise define the top-level message headers either using interface properties or through the Fields collection.
  • Create and/or modify the message content, including MIME-formatted content.
  • Retrieve the message as a stream encoded using MIME or UUENCODE using the GetStream method.
  • Send or post messages, and respond to existing messages.

All mail headers are available generically through the Fields collection. The most common mail headers, such as To, From, Cc, and Subject, are directly available on the interface.

COM classes that provide implementations of the IMessage interface should also provide implementations of the IBodyPart and IDataSource interfaces. These interfaces can be retrieved in the following ways:

  • Using the standard interface navigation mechanisms, such as QueryInterface in C++ and the Set keyword in Microsoft® Visual Basic®
  • Through the Bodypart and DataSource properties on this interface
  • Using the GetInterface method

The GetInterface method is intended primarily to provide scripting languages that do not inherently support interface navigation a means to do so. However, the method can be used from any language.

The methods on the IMessage interface fall into two general categories: those used to send, post, or respond to messages, and those used as aids when creating message content. Methods such as Send, Post, and Reply are examples of the first category, and AddAttachment and CreateMHTMLBody are examples of the second.

The specific behavior for methods such as Send or Post is defined using configuration fields contained within an associated Configuration object.

Example

[Visual Basic]
' Reference to CDO for Exchange 2000 Library
' Reference to ActiveX Data Objects 2.5 Library
' Reference to Active DS Type Library

Sub Main()

    Dim Info As New ADSystemInfo
    Dim InfoNT As New WinNTSystemInfo
    Dim iPer As New CDO.Person
    Dim sTo As String
    Dim sFrom As String
    Dim sSubject As String
    Dim sText As String

    sTo = InfoNT.UserName & "@" & Info.DomainDNSName
    sFrom = sTo
    sSubject = "Subject"
    sText = "Text of message."

    iPer.DataSource.Open "LDAP://" & Info.UserName

    Dim iMbx As CDO.IMailbox
    Set iMbx = iPer

    SendMessageUsingExchange sTo, sFrom, sSubject, sText, iMbx.BaseFolder

End Sub

Sub SendMessageUsingExchange(sTo As String, sFrom As String, sSubject As String, sText As String, sMailboxURL As String)

    Dim iMsg As New CDO.Message
    Dim iBp As CDO.IBodyPart
    Dim Flds As ADODB.Fields
    Dim Conn As New ADODB.Connection
    Dim Stm As ADODB.Stream

    Conn.Provider = "ExOLEDB.DataSource"
    Conn.Open sMailboxURL

    Dim iConf As New CDO.Configuration
    Set Flds = iConf.Fields

    Flds(cdoSendUsingMethod) = cdoSendUsingExchange
    Flds(cdoMailboxURL) = sMailboxURL
    Flds(cdoActiveConnection) = Conn
    Flds.Update

    With iMsg
     Set .Configuration = iConf
         .To = sTo
         .From = sFrom
         .Subject = sSubject
         .TextBody = sText

      Set iBp = .AddAttachment("c:\wordfile.doc")
      Set Stm = .GetStream
      Stm.SaveToFile "c:\mysavedmessage.eml", adSaveCreateOverWrite
        .Send
    End With

End Sub
[C++,IDL]
 /*
  You must have the following paths in your
  include path:
  %CommonProgramFiles%\system\ado
  %CommonProgramFiles%\microsoft shared\cdo
  are in the INCLUDE path.
  Import the type libraries into the project:

  #import <msado15.dll> no_namespace raw_interfaces_only
  #import <cdoex.dll>   no_namespace raw_interfaces_only

 */
#ifndef _CORE_EXAMPLE_HEADERS_INCLUDED
#define _CORE_EXAMPLE_HEADERS_INCLUDED
#import <msado15.dll> no_namespace
#import <cdoex.dll> no_namespace
#include <iostream.h>
#endif

IMessagePtr CreateSampleMessage() {

   IMessagePtr         pmsg(__uuidof(Message));
   IBodyPartPtr      bp;
   IConfigurationPtr   config(__uuidof(Configuration));
   FieldsPtr         flds;
   FieldPtr         fld;
   _StreamPtr         stm;

   _bstr_t bstrEmpty("");

   pmsg->To      = "\"Some One\" <someone@microsoft.com>, \"Another\" <another@microsoft.com>";
   pmsg->From      = "\"ThirdPerson\" <thirdperson@microsoft.com>, \"Fourth\" <fourth@microsoft.com>";
   pmsg->Sender   = "\"Finally\" <finally@microsoft.com>";
   pmsg->Subject   =   "A really cool message.";

   /*
   ** Get current directory so that relative paths
   ** can be expanded. This is needed for AddAttachment.
   */

   LPTSTR buf = NULL;
   DWORD buflen = 0;
   _bstr_t path;
   if( ( buflen = GetCurrentDirectory(buflen,NULL) ) > 0 ) {
      buf = new TCHAR[buflen+1];
      GetCurrentDirectory(buflen+1,buf);
      path = buf;
      delete [] buf;
   }
   else {
      cerr << "Error getting current directory" << endl;;
      throw _com_error(GetLastError());
   }

   try {
      bp = pmsg->AddAttachment(path + _bstr_t("\\..\\misc\\wordfile.doc"),
                           bstrEmpty,
                           bstrEmpty);

      bp->Fields->Item["urn:schemas:mailheader:content-type"]->Value = variant_t("application/msword");
      bp->Fields->Update();
      bp = pmsg->AddAttachment(path + _bstr_t("\\..\\misc\\message2.eml"),
                           bstrEmpty,
                           bstrEmpty);
      bp->Fields->Item["urn:schemas:mailheader:content-type"]->Value = _variant_t("message/rfc822");
      bp->Fields->Update();

      pmsg->CreateMHTMLBody(_bstr_t("http://msdn.microsoft.com"),cdoSuppressAll,_bstr_t(""),_bstr_t(""));
   }
   catch(_com_error e) {
      cerr << "Error creating sample message!" << endl;
      throw e;
   }

   // Save a copy to the local file system.
   stm = pmsg->GetStream();
   stm->SaveToFile(_bstr_t("savemymessage.eml"),adSaveCreateOverWrite);

   return pmsg;
}
[VBScript]
' WSH Source file.
' Assume
'   <reference object="adodb.record"/>
'   <reference object="cdo.message"/>
' exist to resolve type names using the
' type libraries.

Sub SendMessageUsingExchange( sTo, sFrom, sSubject, sText, sMailboxURL)

    Dim iMsg
    Set iMsg = CreateObject("CDO.Message")
    Dim iBp
    Dim Flds
    Dim Conn
    Dim Stm
    Set Conn = CreateObject("ADODB.Connection")
    Conn.Provider = "ExOLEDB.DataSource"
    Conn.Open sMailboxURL

    Dim iConf
    Set iConf = CreateObject("CDO.Configuration")
    Set Flds = iConf.Fields

    Flds(cdoSendUsingMethod)  = cdoSendUsingExchange ' 3
    Flds(cdoMailboxURL)       = sMailboxURL
    Flds(cdoActiveConnection) = Conn
    Flds.Update

    With iMsg
     Set .Configuration = iConf
         .To       = sTo
         .From     = sFrom
         .Subject  = sSubject
         .TextBody = sText

      Set iBp = .AddAttachment("c:\wordfile.doc")
      Set Stm = .GetStream
      Stm.SaveToFile "c:\mysavedmessage.eml", adSaveCreateOverWrite ' 2
        .Send
    End With

End Sub
© 2000-2001 Microsoft Corporation. All rights reserved.


Attachments Property

Returns the collection of attachments for this message.

[Visual Basic]
Property Attachments as IBodyParts
read-only
[C++]
HRESULT get_Attachments(IBodyParts** pVal);
[IDL]
HRESULT [propget] Attachments([out,retval] IBodyParts** pVal);

Remarks

Attachments are stored as body parts in the message's body part hierarchy. The Attachments property returns a BodyParts collection that contains BodyPart objects, each of which contains an attachment to the message. In most cases, attachments are flagged as attachments in MIME-formatted messages by having the MIME header Content-Disposition set to "attachment." However, the status of a given body part as an attachment is implementation-dependent.

Although the Attachments collection is modeled using the IBodyParts interface (exposed by the returned BodyParts object), it is not the same as the collection returned by the IBodyPart.BodyParts collection for the object exposing IMessage. When you request the IMessage.Attachments collection, the object returns a collection of only those BodyPart objects deemed to contain an attachment to the message. For example, consider the following MIME hierarchy for a message:

1. Content-Type: multipart/mixed
2.    Content-Type: multipart/alternative
3.       Content-Type: text/plain
           (text content here)
4.       Content-Type: text/html
           (html content here)
5.    Content-Type:        application/octet-stream
      Content-Disposition: attachment
        (content here)
6.    Content-Type:        application/msword
      Content-Disposition: attachment
        (content here)

In this case, the IMessage.Attachments property would return a BodyParts collection containing two BodyPart objects: one for body part 5 and one for body part 6 as defined in the preceding example. The IBodyPart.BodyParts property would return a BodyParts collection containing three BodyPart objects: one for body part 2, one for body part 5, and one for body part 6.

When you add body parts using the IBodyParts interface passed by the Attachments property, the Content-Disposition header (urn:schemas:mailheader:content-disposition) is automatically set to "attachment."

Example

This code determines how many attachments a message has:

Sub GetAttachmentCount(iMsg As CDO.Message)
  Dim collAtts As CDO.IBodyParts
  Set collAtts = iMsg.Attachments
  If collAtts.Count = 0 Then
    MsgBox "Attachments collection is empty"
  Else
    MsgBox "Message has " & collAtts.Count & " attachments"
  End If
End Sub

See Also

IBodyParts Interface

© 2000-2001 Microsoft Corporation. All rights reserved.


AutoGenerateTextBody Property

Indicates whether the TextBody of a message should automatically be generated from the contents of the HTMLBody property for a multipart/alternative message.

[Visual Basic]
Property AutoGenerateTextBody as Boolean
[C++]
HRESULT get_AutoGenerateTextBody(VARIANT_BOOL* pVal);
HRESULT put_AutoGenerateTextBody(VARIANT_BOOL Val);
[IDL]
HRESULT [propget] AutoGenerateTextBody([out,retval] VARIANT_BOOL* pVal);
HRESULT [propput] AutoGenerateTextBody([in] VARIANT_BOOL Val);

Remarks

If the AutoGenerateTextBody property is True (VARIANT_TRUE), the contents of the TextBody property are replaced by the plain text equivalent of the HTMLBody property; that is, the TextBody is the HTMLBody content with all HTML markup removed.

The following rules apply to the AutoGenerateTextBody property if it is set to True:

  • Setting HTMLBody causes TextBody to be set immediately.
  • Setting TextBody causes AutoGenerateTextBody to be set to False. Any existing HTML content is not updated.
  • Setting HTMLBody causes MimeFormatted to be set to True.
  • Setting MimeFormatted to False causes AutoGenerateTextBody to be set to False.

When using the AutoGenerateTextBody functionality, always update the HTML version of the message body. Updating the plain text version will not cause new HTML to be generated.

For messages that contain other alternate representations besides HTML and plain text, you must create or update each individually.

The default value of AutoGenerateTextBody is True (VARIANT_TRUE) on newly created messages and False (VARIANT_FALSE) on previously existing messages.

Example

This code takes advantage of the default settings of the AutoGenerateTextBody and IMessage.MimeFormatted properties to send a message with both plain text and HTML versions of the same text:

[Visual Basic]
Dim iMsg As New CDO.Message
Dim strHTML As String
strHTML = "<HTML><h1>Hello There</h1></HTML>"
Set iMsg = New CDO.Message
With iMsg
  .To = "Somebody@microsoft.com"
  .From = "another@microsoft.com"
  .Subject = "Sample multipart/alternative message"
  .HTMLBody = strHTML ' .TextBody gets generated automatically
  .Send
End With
[C++,IDL]
/*
 You must have the following paths in your
 INCLUDE path.
 %CommonProgramFiles%\system\ado
 %CommonProgramFiles%\microsoft shared\cdo

*/
#ifndef _CORE_EXAMPLE_HEADERS_INCLUDED
#define _CORE_EXAMPLE_HEADERS_INCLUDED
#import <msado15.dll> no_namespace
#import <cdoex.dll> no_namespace
#include <iostream.h>
#endif

void IMessage_AutoGenerateTextBody_Example() {

   try {
      IMessagePtr iMsg(__uuidof(Message));
      _bstr_t html   = "<HTML><h1>Hello There</h1></HTML>";
      iMsg->To       = "Somebody@microsoft.com" ;
      iMsg->From     = "another@microsoft.com" ;
      iMsg->Subject  = "Sample multipart/alternative message" ;
      iMsg->HTMLBody = html;
      iMsg->Send();
      iMsg = NULL;

   }
   catch(_com_error e) {
      throw e;
   }
}


BCC Property

The hidden carbon copy (Bcc) recipients for this message.

[Visual Basic]
Property BCC as String
[C++]
HRESULT get_BCC(BSTR* pVal);
HRESULT put_BCC(BSTR Val);
[IDL]
HRESULT [propget] BCC([out,retval] BSTR* pVal);
HRESULT [propput] BCC([in] BSTR Val);

Remarks

This property is also available as the urn:schemas:mailheader:bcc and urn:schemas:httpmail:bcc fields.

The string in the BCC property can represent a single recipient or multiple recipients. Each address in the list must be a full messaging address, for example,

"User" <UserAddress@microsoft.com>

where User is the friendly name and <UserAddress@microsoft.com> is the actual e-mail address.

Commas separate multiple recipients in the list:

"User1" <User1@microsoft.com>, "User2" <User2@microsoft.com>, "User3" <User3@microsoft.com>

Commas are not used as separators when enclosed in double quotes, such as:

"Dan K. Bacon, Jr." <dan@microsoft.com>

The friendly name must include the quotation marks in the property, thus when setting this property you will need to use double quotes or other appropriate techniques to include them.

The following are examples of setting this property:

iMsg.To = " ""Dan K. Bacon, Jr."" <jjones@microsoft.com>, ""Kate Dresen"" <kate@microsoft.com>"

in Visual Basic, or

pMsg->put_To(_bstr_t("\"Dan K. Bacon, Jr.\" <dan@microsoft.com>, \"Kate Dresen\" <kate@microsoft.com>"));

in C++.

In keeping with the privacy intended by blind copies, BCC is regarded as an envelope property rather than a message property. Accordingly, the corresponding header field and its contents are removed when the message is delivered, and you should always expect the BCC property to be empty on a received message.

The default value of BCC is an empty string.

See Also

urn:schemas:mailheader:bcc Field

urn:schemas:httpmail:bcc Field


BodyPart Property

The IBodyPart interface on this object.

[Visual Basic]
Property BodyPart as IBodyPart
read-only
[C++]
HRESULT get_BodyPart(IBodyPart** pVal);
[IDL]
HRESULT [propget] BodyPart([out,retval] IBodyPart** pVal);

Remarks

This property returns the IBodyPart interface on the object, and acts as shorthand in place of standard interface navigation such as QueryInterface or the IMessage.GetInterface method used by scripting languages.

Example

[Visual Basic]
Dim iMsg As New CDO.Message
Dim iBp As CDO.IBodyPart ' for IBodyPart on message

   'Get IBodyPart using BodyPart property
Set iBp = iMsg.BodyPart

Set iBp = Nothing ' Release
   ' Get IBodyPart using QI
Set iBp = iMsg

Set iBp = Nothing ' Release
[C++,IDL]
/*
 You must have the following paths in your
 INCLUDE path.
 %CommonProgramFiles%\system\ado
 %CommonProgramFiles%\microsoft shared\cdo

*/
#ifndef _CORE_EXAMPLE_HEADERS_INCLUDED
#define _CORE_EXAMPLE_HEADERS_INCLUDED
#import <msado15.dll> no_namespace
#import <cdoex.dll> no_namespace
#include <iostream.h>
#endif

void IMessage_BodyPart_Example() {

   /*
   ** When using C++, avoid the interface
   ** properties and access the object's
   ** interface directly.
   */
   IBodyPart*   pBp   =   NULL;
   HRESULT hr = CoCreateInstance(
      __uuidof(Message),
      NULL,
      CLSCTX_SERVER,
      __uuidof(IBodyPart),
      (void**)&pBp);

   // ...

   pBp->Release();

}


CC Property

The informational (carbon copy, or Cc) recipients for this message.

[Visual Basic]
Property CC as String
[C++]
HRESULT get_CC(BSTR* pVal);
HRESULT put_CC(BSTR Val);
[IDL]
HRESULT [propget] CC([out,retval] BSTR* pVal);
HRESULT [propput] CC([in] BSTR Val);

Remarks

This property is also available as the urn:schemas:mailheader:cc and urn:schemas:httpmail:cc fields.

The string in the CC property can represent a single recipient or multiple recipients. See the BCC property for more information on formatting and setting e-mail address properties.

You must set at least one recipient in at least one of the BCC, CC, or To properties. If you call the Post or Send method without doing this, an error is returned.

The default value of CC is an empty string.

See Also

urn:schemas:mailheader:cc Field

urn:schemas:httpmail:cc Field


Configuration Property

The Configuration object for the message.

[Visual Basic]
Property Configuration as IConfiguration
[C++]
HRESULT get_Configuration(IConfiguration** pVal);
HRESULT put_Configuration(IConfiguration* Val);
[IDL]
HRESULT [propget] Configuration([out,retval] IConfiguration** pVal);
HRESULT [propput] Configuration([in] IConfiguration* Val);

Remarks

The configuration settings used for the current message are contained in the Configuration object (exposing the IConfiguration interface) referenced by this property. To change the settings, you can retrieve a reference to the object and modify the settings using the IConfiguration.Fields collection, or you can create a new instance of the Configuration COM class, modify the settings, and set the object reference to the Configuration property.

If you do not explicitly set or modify the associated Configuration object, the message is processed using a default configuration. For optimal performance, it is recommended that you create a Configuration object, set the configuration fields manually, and set the object to the Configuration property on each Message object.

You cannot replace the default configuration. If you wish to alter configuration information for messages, you must modify the fields in each object's associated Configuration object. If a single configuration is to be used for a set of messages, you can simply create a new Configuration object, modify the fields, and then reference this Configuration object in all the intended messages.


DataSource Property

The IDataSource interface on this object.

[Visual Basic]
Property DataSource as IDataSource
read-only
[C++]
HRESULT get_DataSource(IDataSource** pVal);
[IDL]
HRESULT [propget] DataSource([out,retval] IDataSource** pVal);

Remarks

You can use the DataSource property to navigate to the IDataSource interface on the object implementing IMessage. This is equivalent to using QueryInterface in C++ or Set in Visual Basic, or using the IMessage.GetInterface method.


DSNOptions Property

The Delivery Status Notification (DSN) options for the message.

[Visual Basic]
Property DSNOptions as CdoDSNOptions
[C++]
HRESULT get_DSNOptions(CdoDSNOptions* pVal);
HRESULT put_DSNOptions(CdoDSNOptions Val);
[IDL]
HRESULT [propget] DSNOptions([out,retval] CdoDSNOptions* pVal);
HRESULT [propput] DSNOptions([in] CdoDSNOptions Val);

Remarks

The CdoDSNOptions enumeration is provided for this property.

A DSN is essentially a request for a receipt of message delivery status. The request can be for the enumerated delivery conditions. Note that DSNs can pass through numerous message transfer agents and thus return receipts can have different meanings.

DSNOptions defines the type of DSN requested as described in RFC 1894. The RFC covers the nature and uses of DSNs in depth.

See Also

IMessage.MDNRequested Property

CdoDSNOptions Enum

© 2000-2001 Microsoft Corporation. All rights reserved.


EnvelopeFields Property

The SMTP and NNTP envelope fields of the message.

[Visual Basic]
Property EnvelopeFields as ADODB.Fields
read-only
[C++]
HRESULT get_EnvelopeFields(Fields** pVal);
[IDL]
HRESULT [propget] EnvelopeFields([out,retval] Fields** pVal);

Remarks

The EnvelopeFields collection returns a restricted collection of fields that are not available through the Fields collection on a CDO object. The envelope field collection contains NNTP and SMTP transport envelope fields that are only available for the object when it is passed to a transport event sink. For more information about writing event sinks using CDO, see SMTP and NNTP Transport Event Sinks.

For SMTP OnArrival sinks, all fields in the collection are within the http://schemas.microsoft.com/cdo/smtpenvelope/ namespace.

For NNTP OnPostEarly, OnPost, and OnPostFinal event sinks, all fields reside in the http://schemas.microsoft.com/cdo/nntpenvelope/ namespace.

See Also

SMTP/NNTP Transport Event Sinks with CDO

http://schemas.microsoft.com/cdo/smtpenvelope/ Namespace

http://schemas.microsoft.com/cdo/nntpenvelope/ Namespace


Fields Property

The Fields collection for the object.

[Visual Basic]
Property Fields as ADODB.Fields
read-only
[C++]
HRESULT get_Fields(Fields** pVal);
[IDL]
HRESULT [propget] Fields([out,retval] Fields** pVal);

Remarks

The Fields property obtains a collection of ADO Field objects each of which contains a field relating to the message.

Note When you use the ADO Fields.Update method, field values are updated only in memory. You must call IDataSource.Save to save the changes to the Web Storage System. To get the IDataSource interface, use the GetInterface method on the CDO object.

Example

This example determines how many fields a message has:

Dim iMsg As New CDO.Message
Dim collFields As Fields
Set collFields = iMsg.Fields

If collFields.Count = 0 Then
  MsgBox "Fields collection is empty"
Else
  MsgBox "Message has " & collFields.Count & " fields"
End If
© 2000-2001 Microsoft Corporation. All rights reserved.


FollowUpTo Property

The newsgroups to which any responses to this message should be posted.

[Visual Basic]
Property FollowUpTo as String
[C++]
HRESULT get_FollowUpTo(BSTR* pVal);
HRESULT put_FollowUpTo(BSTR Val);
[IDL]
HRESULT [propget] FollowUpTo([out,retval] BSTR* pVal);
HRESULT [propput] FollowUpTo([in] BSTR Val);

Remarks

This property is also available as the urn:schemas:mailheader:followup-to field.

The string in the FollowUpTo property can represent a single newsgroup or multiple newsgroups. A newsgroup name is a set of words concatenated by periods:

"microsoft.public.discussion"

Multiple newsgroups in the list are separated by commas:

"alt.sample,sample.newsgroup.name,microsoft.public.chat"

A newsgroup name cannot contain a comma.

Only existing newsgroups should be specified. If a newsgroup with a given name does not exist, posting to that name does not cause the newsgroup to be created.

If FollowUpTo is not set, responses are posted to the newsgroups specified by the Newsgroups property.

The default value of FollowUpTo is an empty string.

See Also

urn:schemas:mailheader:followup-to Field


From Property

The e-mail addresses of the principal author or authors of this message.

[Visual Basic]
Property From as String
[C++]
HRESULT get_From(BSTR* pVal);
HRESULT put_From(BSTR Val);
[IDL]
HRESULT [propget] From([out,retval] BSTR* pVal);
HRESULT [propput] From([in] BSTR Val);

Remarks

This property is also available as the urn:schemas:mailheader:from and urn:schemas:httpmail:from fields.

The string in the From property represents the messaging users designated by their full messaging addresses. See the BCC property for more information on formatting and setting e-mail address properties.

If you do not set From before calling the IMessage.Send method, CDO uses the IMessage.Sender property instead. Either the From or the Sender property, or both, must be set prior to sending a message. If neither From nor Sender is set before calling the Send method, an exception is raised. If you do not set From before calling the Post method, an exception is raised; the Sender property is not used for NNTP.

The distinction between the From and Sender properties is that Sender represents the messaging user that actually submits the message, while From designates its principal author(s). If these are the same messaging user, it is only necessary to set From, and it is recommended to leave Sender unset in this case.

See Also

urn:schemas:mailheader:from Field

urn:schemas:httpmail:from Field


HTMLBody Property

The HTML representation of the message.

[Visual Basic]
Property HTMLBody as String
[C++]
HRESULT get_HTMLBody(BSTR* pVal);
HRESULT put_HTMLBody(BSTR Val);
[IDL]
HRESULT [propget] HTMLBody([out,retval] BSTR* pVal);
HRESULT [propput] HTMLBody([in] BSTR Val);

Remarks

This property is also available as the urn:schemas:httpmail:htmldescription entry in the schema.

To construct a MIME message containing both the plain text and HTML versions of the body, you can set the message's ContentMediaType property on the IBodyPart interface to "multipart/alternative", the first body part's ContentMediaType to "text/plain", and the second body part's ContentMediaType to "text/richtext" or "text/html". Alternatively, you can use the AutoGenerateTextBody and MimeFormatted properties to automate some of this process. When these properties are both True and you set HTMLBody, CDO automatically sets the TextBody property to the plain text equivalent.

If you set MimeFormatted to False, the HTMLBody property is removed from the message and the HTML text is lost.

To access the corresponding plain text string, use the TextBody property.

You can access the BodyPart object containing the HTML for the message using the IMessage.HTMLBodyPart property.

The HTMLBody property returns an empty string if it has never been set. If you need to determine whether this is the case or whether the HTML text is present but currently an empty string, use the IMessage.HTMLBodyPart method to access the BodyPart object containing the HTML for the message.

The default value of HTMLBody is an empty string.

See Also

urn:schemas:mailheader:htmldescription Field

IMessage.HTMLBodyPart Property

© 2000-2001 Microsoft Corporation. All rights reserved.


HTMLBodyPart Property

The BodyPart object containing the HTML representation of the message.

[Visual Basic]
Property HTMLBodyPart as IBodyPart
read-only
[C++]
HRESULT get_HTMLBody(IBodyPart** pVal);
[IDL]
HRESULT [propget] HTMLBodyPart([out,retval] IBodyPart** pVal);

Remarks

The HTMLBodyPart property can be used to quickly access a reference to the BodyPart object that contains the HTML portion of the message (if any). That is, rather than having to enumerate the BodyPart hierarchy of the message seeking the object with Content-Type set to "text/html," you can use HTMLBodyPart to return a reference immediately. A similar mechanism is available for the text/plain portion of the message (if any) using the IMessage.TextBody and IMessage.TextBodyPart properties.

The content of the BodyPart object referenced by HTMLBodyPart can be updated using the IMessage.HTMLBody property. The HTMLBody property can only be used to update the contents, not the mail headers themselves.

CDO returns an error if the body part does not exist.

See Also

IMessage.HTMLBody

IMessage.AutoGenerateTextBody

IMessage.TextBody

IMessage.TextBodyPart

© 2000-2001 Microsoft Corporation. All rights reserved.


Keywords Property

A list of keywords for this message.

[Visual Basic]
Property Keywords as String
[C++]
HRESULT get_KeyWords(BSTR* pVal);
HRESULT put_KeyWords(BSTR Val);
[IDL]
HRESULT [propget] Keywords([out,retval] BSTR* pVal);
HRESULT [propput] Keywords([in] BSTR Val);

Remarks

This property is also available as the urn:schemas:mailheader:keywords field.

A message's keywords can be useful in determining if the message is of interest to the reader, or in searching for relevant messages in a collection.

The string in the Keywords property can represent a single keyword or multiple keywords. A keyword string can optionally contain spaces:

"1997 payroll"

Multiple keywords in the list are separated by commas:

operating systems, Windows NT, functions

Because the comma is this field's delimiter, a keyword cannot contain a comma. Attempting to add a keyword containing a comma will result in two keywords, separated by the comma.

The selection of keywords is at the discretion of the messaging users that post and read the message.

The default value of Keywords is an empty string.

See Also

urn:schemas:mailheader:keywords


MDNRequested Property

Indicates whether a Message Disposition Notification (MDN) report is requested for a message.

[Visual Basic]
Property MDNRequested as Boolean
[C++]
HRESULT get_MDNRequested(VARIANT_BOOL* pVal);
HRESULT put_MDNRequested(VARIANT_BOOL Val);
[IDL]
HRESULT [propget] MDNRequested([out,retval] VARIANT_BOOL* pVal);
HRESULT [propput] MDNRequested([in] VARIANT_BOOL Val);

Remarks

A Message Disposition Notification (MDN) is a request for disposition information from a recipient after the message has been successfully delivered. This disposition might include whether the message was displayed, printed, or deleted without display, or if a recipient refused to send MDNs. The message sender or an intermediary Message Transfer Agent can request MDNs. The returned MDN report message is nested in a message with Content-Type of multipart/report. RFC 2298 describes MDNs, their function and format.

To request an MDN for a message, set the urn:schemas:mailheader:disposition-notification-to header field to the sender's e-mail address. Optionally, set the urn:schemas:mailheader:disposition-notification-options header field to the appropriate value. Then send the message. To remove a previously added MDN header field, delete it using the IMessage.Fields.Delete method.

Example

[VBScript]
' WSH Source file.
' Assume
'   <reference object="adodb.record"/>
'   <reference object="cdo.message"/>
' exist to resolve type names using the
' type libraries.

sub mdnexample()

 set msg = createobject("cdo.message")

 with msg
   set conf = .configuration
   with conf
     .fields(cdoSendEmailAddress)          = "user1@microsoft.com"
     .fields(cdoSendUserReplyEmailAddress) = "user2@microsoft.com"
     .fields.update
   end with

   .to            = "user3@microsoft.com"
   .from          = "user1@microsoft.com"
   .subject       = "Need to know you got this."
   .textbody      = "here is the important message."
   .mdnrequested  = true
   .fields(cdoDispositionNotificationTo) = "user1@microsoft.com"
   .fields.update

   wscript.echo .getstream.readtext
   ' .send

  ' next, send the message to others without MDNs

  .fields.delete(cdoDispositionNotificationTo)
  .fields.update
  .To             = "user4@microsoft.com"

  wscript.echo .getstream.readtext
  ' .send
 end with

end sub
[Visual Basic]
See the VBScript example.
[C++]
See the VBScript example.

See Also

IMessage.DSNOptions Property

© 2000-2001 Microsoft Corporation. All rights reserved.


MimeFormatted Property

Indicates whether or not this message is to be formatted using the Multipurpose Internet Mail Extensions (MIME) formatting scheme.

[Visual Basic]
Property MimeFormatted as Boolean
[C++]
HRESULT get_MimeFormatted(VARIANT_BOOL* pVal);
HRESULT put_MimeFormatted(VARIANT_BOOL Val);
[IDL]
HRESULT [propget] MimeFormatted([out,retval] VARIANT_BOOL* pVal);
HRESULT [propput] MimeFormatted([in] VARIANT_BOOL Val);

Remarks

If MimeFormatted is set to True, CDO automatically sets the message's IBodyPart.ContentMediaType property to "multipart/alternative". However, subsequent actions can change this setting. Adding a body part, for example, changes ContentMediaType to "multipart/mixed", and adding an associated URL changes it to "multipart/related".

If MimeFormatted is False and you set the HTMLBody property, CDO sets MimeFormatted to True. If you set MimeFormatted to False, the HTMLBody property is removed from the message and the HTML text is lost.

If you prepare a message with MimeFormatted set to True and later change it to False, all the body parts are made into attachments and marked for encoding with the UUENCODE mechanism. Encoding only takes place when you call the Send or Post method.

The default value of MimeFormatted is True.


Newsgroups Property

The newsgroup recipients for the message.

[Visual Basic]
Property Newsgroups as String
[C++]
HRESULT get_Newsgroups(BSTR* pVal);
HRESULT put_Newsgroups(BSTR Val);
[IDL]
HRESULT [propget] Newsgroups([out,retval] BSTR* pVal);
HRESULT [propput] Newsgroups([in] BSTR Val);

Remarks

This property is also available as the urn:schemas:mailheader:newsgroups entry in the schema.

The string in the Newsgroups property can represent a single newsgroup or multiple newsgroups. A newsgroup name is a set of words concatenated by periods:

microsoft.public.discussion

Commas separate multiple newsgroups in the list:

alt.sample,sample.newsgroup.name,microsoft.public.chat

A newsgroup name cannot contain a comma.

Only existing newsgroups should be specified. If a newsgroup with a given name does not exist, posting to that name does not cause the newsgroup to be created.

The Newsgroups property is required on news messages. If you do not set it before calling the IMessage.Post method, an error is returned.

Responses to this message are posted to the same newsgroups unless the IMessage.FollowUpTo property is set.

The default value of Newsgroups is an empty string.

See Also

urn:schemas:mailheader:newsgroups


Organization Property

Contains a description of the organization to which the sender belongs.

[Visual Basic]
Property Organization as String
[C++]
HRESULT get_Organization(BSTR* pVal);
HRESULT put_Organization(BSTR Val);
[IDL]
HRESULT [propget] Organization([out,retval] BSTR* pVal);
HRESULT [propput] Organization([in] BSTR Val);

Remarks

This property is also available as the urn:schemas:mailheader:organization field.

The Organization property is used for the NNTP Organization header field. The purpose of this field is to supply a short phrase meaningfully describing the sender's organization, such as "Sample Corporation, Payroll Department". This can be easier to recognize than a cryptic messaging address like "Q1006453@pd.sc.tld".

The default value of Organization is an empty string.

See Also

urn:schemas:mailheader:organization


ReceivedTime Property

The date/time this message was delivered to the server.

[Visual Basic]
Property ReceivedTime as Date
read-only
[C++]
HRESULT get_RecievedTime(DATE* pVal);
[IDL]
HRESULT [propget] ReceivedTime([out,retval] DATE* pVal);

Remarks

This property is also available as the urn:schemas:httpmail:datereceived field.

The ReceivedTime property is determined from the last entry for "Received:" in the SMTP headers.

The IMessage.SentOn and ReceivedTime properties hold the date/time in the time zone specified in the associated Configuration object using the urn:schemas:calendar:timezoneid field. If the time zone is not set in the IConfiguration.Fields collection, the date and time are held in the server's local time zone. If there is no server involved, the receiving user's local time zone is used.

If ReceivedTime could not be set from the headers, attempting to read it results in an error of CDO_E_PROP_NOT_FOUND.

See Also

IMessage.SentOn

urn:schemas:httpmail:datereceived Field

urn:schemas:calendar:timezoneid Field


ReplyTo Property

The address to which replies should be sent.

[Visual Basic]
Property ReplyTo as String
[C++]
HRESULT get_ReplyTo(BSTR* pVal);
HRESULT put_ReplyTo(BSTR Val);
[IDL]
HRESULT [propget] ReplyTo([out,retval] BSTR* pVal);
HRESULT [propput] ReplyTo([in] BSTR Val);

Remarks

This property is also available as the urn:schemas:mailheader:reply-to property.

The string in the ReplyTo property should represent a single messaging user designated by a full messaging address. For example, all of the following formats qualify as the full messaging address for "User Address:"

"User Address" <UserAddress@microsoft.com>
<UserAddress@microsoft.com>
UserAddress@microsoft.com

Multiple addresses are not recommended in the ReplyTo property. The SMTP protocol requires that the ReplyTo property must designate a single messaging user. The name of a list or a group is not allowed. However, replies can also be copied to addresses given in the To, CC, and BCC properties.

If ReplyTo is not set, the Reply and ReplyAll methods address the reply to the messaging address in the From property.

The default value of ReplyTo is an empty string.

See Also

urn:schemas:mailheader:reply-to


Sender Property

The address of the user or agent that actually submits the message.

[Visual Basic]
Property Sender as String
[C++]
HRESULT get_Sender(BSTR* pVal);
HRESULT out_Sender(BSTR Val);
[IDL]
HRESULT [propget] Sender([out,retval] BSTR* pVal);
HRESULT [propput] Sender([in] BSTR Val);

Remarks

The distinction between the From and Sender properties is that the Sender property identifies the address of the user or entity that actually submits the message, whereas the From property designates its principal author or authors. By convention (RFC 822), multiple addresses are not identified in the Sender property.

The Sender property is normally used when:

  • There are multiple addresses in the From header. The sender is the e-mail address of the person or entity in the From field that actually submitted the message.
  • The person or entity that is submitting the message is not included in the From field.

When posting a message, the Sender property is not used; the From property must be specified.

This property is also available as the urn:schemas:mailheader:sender and urn:schemas:httpmail:sender fields.

See Also

urn:schemas:mailheader:sender Field

urn:schemas:httpmail:sender Field


SentOn Property

The date/time this message was submitted to the server.

[Visual Basic]
Property SentOn as Date
read-only
[C++]
HRESULT get_SentOn(DATE* pVal);
[IDL]
HRESULT [propget] SentOn([out,retval] DATE* pVal);

Remarks

The SentOn property is determined from the last entry for "Date:" in the SMTP headers, accessible from the urn:schemas:mailheader:date entry in the schema.

The IMessage.SentOn and IMessage.ReceivedTime properties hold the date/time in the time zone specified in the associated Configuration object using the urn:schemas:calendar:timezoneid field. If the time zone is not set in the IConfiguration.Fields collection, the date and time are held in the server's local time zone. If there is no server involved, the receiving user's local time zone is used.

See Also

urn:schemas:mailheader:date

urn:schemas:calendar:timezoneid Field


Subject Property

The subject of this message.

[Visual Basic]
Property Subject as String
[C++]
HRESULT get_Subject(BSTR* pVal);
HRESULT put_Subject(BSTR Val);
IDL]
HRESULT [propget] Subject([out,retval] BSTR* pVal);
HRESULT [propput] Subject([in] BSTR Val);

Remarks

This property is also available as the urn:schemas:mailheader:subject and urn:schemas:httpmail:subject fields.

The Subject property is required on news messages. If you do not set it before calling the Post method, an error is returned.

The default value of Subject is an empty string.

See Also

urn:schemas:mailheader:subject

urn:schemas:httpmail:subject


TextBody Property

The plain text representation of the body of this message.

[Visual Basic]
Property TextBody as String
[C++]
HRESULT get_TextBody(BSTR* pVal);
HRESULT put_TextBody(BSTR Val);
IDL]
HRESULT [propget] TextBody([out,retval] BSTR* pVal);
HRESULT [propput] TextBody([in] BSTR Val);

Remarks

This property is also available as the urn:schemas:httpmail:textdescription entry in the schema.

To construct a MIME message containing both the plain text and HTML versions of the body, you can set the message's IBodyPart.ContentMediaType property to "multipart/alternative", the first body part's ContentMediaType to "text/plain", and the second body part's ContentMediaType to "text/richtext" or "text/html". Alternatively, you can use the IMessage.AutoGenerateTextBody and IMessage.MimeFormatted properties to automate some of this process. When these properties are both True and you set HTMLBody, CDO automatically sets the TextBody property to the plain text equivalent.

To access the corresponding HTML text string, use the IMessage.HTMLBody property. To retrieve the BodyPart object that contains the HTML part of the message, use the IMessage.HTMLBodyPart property.

The plain text is also available as a body part object through the IMessage.TextBodyPart method.

The TextBody property returns an empty string if it has never been set. If you need to determine whether this is the case or whether the plain text is present but currently an empty string, use the IMessage.TextBodyPart method to retrieve the BodyPart object containing the text portion of the message.

The default value of TextBody is an empty string.

See Also

urn:schemas:httpmail:textdescription, IMessage.TextBodyPart, IMessage.AutoGenerateTextBody


TextBodyPart Property

Returns a body part object containing the text content of this message.

[Visual Basic]
Property TextBodyPart as IBodyPart
read-only
[C++]
HRESULT get_TextBodyPart(IBodyPart** pVal);
[IDL]
HRESULT [propget] TextBodyPart([out,retval] IBodyPart** pVal);

Remarks

The TextBodyPart property can be used to quickly access the IBodyPart object reference to the BodyPart object that contains the text portion of the message (if any). That is, rather than having to enumerate the BodyPart hierarchy of the message seeking the object with Content-Type set to "text/plain" you can use TextBodyPart to return a reference immediately. A similar mechanism is available for the text/html portion of the message (if any) using the IMessage.HTMLBody and IMessage.HTMLBodyPart properties.

The content of the BodyPart object referenced by TextBodyPart can be updated using the IMessage.TextBody property. The TextBody property can only be used to update the contents, not the mail headers themselves.

If the requested body part does not exist, the method returns an error.

See Also

IMessage.TextBody

IMessage.AutoGenerateTextBody

IMessage.HTMLBody

IMessage.HTMLBodyPart

© 2000-2001 Microsoft Corporation. All rights reserved.


To Property

Contains a list of principal (To) recipients for this message.

[Visual Basic]
Property To as String
[C++]
HRESULT get_To(BSTR* pVal);
HRESULT put_To(BSTR Val);
IDL]
HRESULT [propget] To([out,retval] BSTR* pVal);
HRESULT [propput] To([in] BSTR Val);

Remarks

This property is also available as the urn:schemas:mailheader:to and urn:schemas:httpmail:to fields.

The string in the To property can represent a single recipient or multiple recipients. See the BCC property for more information on formatting and setting e-mail address properties.

You must set at least one recipient in at least one of the BCC, CC, or To properties. If you call the Post or Send method without designating at least one recipient, an error is returned.

The default value of To is an empty string.

See Also

urn:schemas:mailheader:to

urn:schemas:httpmail:to


AddAttachment Method

Adds an attachment to this message.

[Visual Basic]
Function AddAttachment(
    ByVal URL as String,
   [ByVal UserName as String],
   [ByVal Password as String]
) as IBodyPart
[C++]
HRESULT AddAttachment(
   BSTR URL,
[BSTR UserName,]
  [BSTR Password,]
   IBodyPart** pVal
);
[IDL]
HRESULT AddAttachment(
   [in] BSTR URL,
   [in, optional] BSTR UserName,
   [in, optional] BSTR Password,
   [out,retval] IBodyPart** pVal
);
URL
The full path and file name of the message to be attached to this message.
UserName
An optional user name to use for authentication when retrieving the resource using Hypertext Transfer Protocol (HTTP). This name can be used to set the credentials for basic, NTLM, and Negotiate (Kerberos) authentication packages.
Password
An optional password to use for authentication when retrieving the resource using Hypertext Transfer Protocol (HTTP). This password can be used to set the credentials for basic, NTLM, and Negotiate (Kerberos) authentication packages.

Remarks

The AddAttachment method adds the attachment by first retrieving the resource specified by the Uniform Resource Locator (URL) and then adding the content to the message's Attachments collection within a BodyPart object.

The URL prefixes supported in the URL parameter are file://, ftp://, http://, and https://. The default prefix is file://. This facilitates designation of paths starting with drive letters and of universal naming convention (UNC) paths.

The MIMEFormatted property determines how the attachment is formatted when the message is serialized for delivery to a Simple Mail Transfer Protocol (SMTP) service. If this property is set to True, the attachment is formatted using Multipurpose Internet Mail Extensions (MIME). If the property is set to False, the attachment is added to the serialized content stream in UUENCODE format.

If you populate the HTMLBody property before calling the AddAttachment method, any inline images are displayed as part of the message.

Use the UserName and Password parameters when you are requesting Web pages using Hypertext Transfer Protocol (HTTP) from a server that requires client authentication. If the Web server supports only the basic mechanism, these credentials must be supplied. By default the current process security context is used to authenticate when using the NTLM or Negotiate (Kerberos) security packages; however, you can specify alternative credentials with the UserName and Password parameters.

Example

Dim iMsg As New CDO.Message
Dim iBp As CDO.IBodyPart
Set iBp = iMsg.AddAttachment("http://example.microsoft.com")
Set iBp = iMsg.AddAttachment("c:\myfiles\file.doc")
' ..
iMsg.Send


AddRelatedBodyPart Method

The AddRelatedBodyPart method adds a BodyPart object that is referenced by content in the HTML body of the message.

[Visual Basic]
Function AddRelatedBodyPart(
    ByVal URL as String,
    ByVal Reference as String,
    ByVal ReferenceType as CdoReferenceType,
   [ByVal UserName as String],
   [ByVal Password as String]
) as IBodyPart
[C++]
HRESULT AddRelatedBodyPart(
    BSTR URL,
    BSTR Reference,
    CdoReferenceType ReferenceType,
   [BSTR UserName,]
   [BSTR Password,]
    IBodyPart** pVal
);
[IDL]
HRESULT AddRelatedBodyPart(
   [in] BSTR URL,
   [in] BSTR Reference,
   [in] CdoReferenceType ReferenceType,
   [in, optional] BSTR UserName,
   [in, optional] BSTR Password,
   [out,retval] IBodyPart** pVal
);
URL
The full path and file name of the resource to be associated with the new body part.
Reference
The Content-ID or Content-Location header that a rendering client can use to reference the new body part.
ReferenceType
The method of referencing the new body part. This parameter will determine which type of Content header is placed in this Multipurpose Internet Mail Extensions (MIME) subpart. The value is one of the CdoReferenceType enumerated values.

See Request for Comments (RFC) 2110 and RFC 2111 for further information on using Content-ID and Content-Location headers in messages formatted in MIME Encapsulation of Aggregate HTML Documents (MHTML).

UserName
An optional user name to use for authentication when retrieving the resource using Hypertext Transfer Protocol (HTTP). This name can be used to set the credentials for basic, NTLM, and Negotiate (Kerberos) authentication packages.
Password
An optional password to use for authentication when retrieving the resource using Hypertext Transfer Protocol (HTTP). This password can be used to set the credentials for basic, NTLM, and Negotiate (Kerberos) authentication packages.

Remarks

This method is intended to associate a Uniform Resource Locator (URL) within the content of a Multipurpose Internet Mail Extensions (MIME) body part to another body part in the MIME hierarchy. The AddRelatedBodyPart method is commonly used to attach graphics inline instead of referring to them using a URL.

The AddRelatedBodyPart method creates a body part by getting the contents specified by the URL parameter. It returns the IBodyPart object reference on the BodyPart object that is added to the collection of body parts of this message.

Calling the AddRelatedBodyPart method causes this message to become an MHTML-formatted message. Collaboration Data Objects (CDO) automatically sets the MimeFormatted property to True and constructs the necessary multipart/related body part hierarchy. The ContentMediaType property of the new HTML body part is automatically set to text/html. The Content-ID or Content-Location header field of the related body part is set using the mechanism specified using the Reference and ReferenceType parameters, and its Content-Disposition header field is set to inline.

Normally, you populate the IMessage.HTMLBody property before calling the AddRelatedBodyPart method. The HTML can contain links to graphics and other resources. If the HTMLBody property is not set, or if its tag does not match the Content-Location header field of the new body part, the AddRelatedBodyPart method adds the body part without relating it to anything else.

Use the UserName and Password parameters when you are requesting Web pages using Hypertext Transfer Protocol (HTTP) from a server that requires client authentication. If the Web server supports only the basic authentication mechanism, these credentials must be supplied. By default the current process security context is used to authenticate when using the NTLM or Negotiate (Kerberos) security packages; however, you can specify alternative credentials with the UserName and Password parameters.

Example

Dim iMsg As New CDO.Message
' ... .MimeFormatted defaults to True on the new message ...
Dim strHTML As String ' string in which to build up HTML body
' ...
Set iMsg = New CDO.Message
strHTML = "<!DOCTYPE HTML PUBLIC ""-//IETF//DTD HTML//EN"">" & NL
strHTML = strHTML & "<HTML>"
strHTML = strHTML & "  <HEAD>"
strHTML = strHTML & "    <TITLE>Sample GIF</TITLE>"
strHTML = strHTML & "  </HEAD>"
strHTML = strHTML & "  <BODY><P>"
strHTML = strHTML & "   <IMG src=""XYZ.gif""></p><p>Inline graphics</P>"
strHTML = strHTML & "  </BODY>"
strHTML = strHTML & "</HTML>"

iMsg.HTMLBody = strHTML

iMsg.AddRelatedBodyPart "D:\wwwroot\XYZ.gif", "XYZ.gif", cdoRefTypeId

iMsg.Send

See Also

CdoReferenceType Enum

© 2000-2001 Microsoft Corporation. All rights reserved.


CreateMHTMLBody Method

The CreateMHTMLBody method converts the contents of an entire Web page into a MIME Encapsulation of Aggregate HTML Documents (MHTML) formatted message body.

[Visual Basic]
Sub CreateMHTMLBody(
   ByVal URL as String,
   [ByVal Flags as CdoMHTMLFlags = 0],
   [ByVal UserName as String],
   [ByVal Password as String]
)
[C++]
HRESULT CreateMHTMLBody(
   BSTR URL,
   CdoMHTMLFlags Flags=cdoSuppressNone,
   BSTR UserName,
   BSTR Password
);
[IDL]
HRESULT CreateMHTMLBody(
   [in] BSTR URL,
   [in, defaultvalue(0), optional] CdoMHTMLFlags Flags,
   [in, optional] BSTR UserName,
   [in, optional] BSTR Password
);
URL
The full path and file name of the Web page.
Flags
A bit mask of flags controlling inclusion of items from the Web page as related body parts. The flags are defined in the CdoMHTMLFlags enumeration. The default value of Flags is CdoSuppressNone.
UserName
An optional user name to use for authentication when retrieving the resource using Hypertext Transfer Protocol (HTTP). This name can be used to set the credentials for basic, NTLM, and Negotiate (Kerberos) authentication packages.
Password
An optional password to use for authentication when retrieving the resource using Hypertext Transfer Protocol (HTTP). This password can be used to set the credentials for basic, NTLM, and Negotiate (Kerberos) authentication packages.

Remarks

The CreateMHTMLBody method scans the Web page for links and attachments, and creates appropriate body parts on this message.

CreateMHTMLBody adds new body parts to the message but does not delete any previously existing ones. However, it replaces any previous contents of the HTMLBody property. In so doing, it rewrites file-reference URLs as Content-ID URLs. For example,

<IMG SRC="http://abc/xyz.gif">

might be rewritten as

<IMG SRC="cid:000301bd9ad5$09a6b9f8$_CDOEX">

The Content-ID URL uniquely references the individual body part that contains the image. For more information on Content-ID, see MIME Headers.

Use the UserName and Password parameters when you are requesting Web pages using Hypertext Transfer Protocol (HTTP) from a server that requires client authentication. If the Web server supports only the basic authentication mechanism, these credentials must be supplied. By default the current process security context is used to authenticate when using the NTLM or Negotiate (Kerberos) security packages; however, you can specify alternative credentials with the UserName and Password parameters.

It is recommended that you create a new message before calling CreateMHTMLBody. If you decide to reuse a message, use the IBodyParts.DeleteAll method to remove all BodyPart objects from the message.

The CreateMHTMLBody method makes use of the following fields in the http://schemas.microsoft.com/cdo/configuration/ namespace. These fields are defined in the Configuration object referenced by the IMessage.Configuration property.

Field | How the Value is Used.
httpcookies | If defined, these cookies are sent with the request for the resource.
urlgetlatestversion
 If set to True (VARIANT_TRUE), local cached copies of the resource are bypassed and the object requests the resource directly from the Web server.
urlproxyserver
 If set, the TCP/IP connection to the Web server is obtained using the specified proxy server.
urlproxybypass
 If set, the object connects directly to local IP addresses and bypasses the proxy server.

After you call CreateMHTMLBody, you can add or modify body parts, set the TextBody property, and modify HTMLBody.

The CreateMHTMLBody method does case-insensitive pattern matching on the Content-Type header field when loading from a URL. If the resource specified by a URL is not found, an error is returned.

A common use for CreateMHTMLBody is sending the contents of a Web page to a messaging user. This can be useful, for example, for news or stock report services.

Example

Dim iMsg  As New CDO.Message
Dim iConf As New CDO.Configuration
Dim Flds  As ADODB.Fields
Set Flds = iConf.Fields
Flds(cdoURLProxyServer) = "myserver:80"
Flds(cdoURLProxyBypass) = True
Flds(cdoURLGetLatestVersion) = True
Flds.Update

With iMsg
   Set .Configuration = iConf
   .CreateMHTMLBody ("http://example.microsoft.com")
   .To = "MyCustomer@microsoft.com"
   .From = "me@microsoft.com"
   .Subject = "an example mhtml message"
   .Send
End With

See Also

http://schemas.microsoft.com/cdo/configuration/httpcookies Field

http://schemas.microsoft.com/cdo/configuration/urlgetlatestversion Field

http://schemas.microsoft.com/cdo/configuration/urlproxyserver Field

http://schemas.microsoft.com/cdo/configuration/urlproxybypass Field

CdoMHTMLFlags Enum

© 2000-2001 Microsoft Corporation. All rights reserved.


Forward Method

The Forward method creates and returns another message that can be used to forward this message.

[Visual Basic]
Function Forward() as CDO.Message
[C++]
HRESULT Forward(IMessage** pVal);
[IDL]
HRESULT Forward([out,retval] IMessage** pVal);

Remarks

The Forward method returns the IMessage interface on the new message.

If the configuration field http://schemas.microsoft.com/cdo/configuration/usemessageresponsetext is set to True (VARIANT_TRUE), then the original message is formatted using the following:

-----Original Message-----
From:"Person" <person@microsoft.com>
Sent:Tue, 23 Mar 1998 12:41:37 -0800
To:"Person A" <personA@microsoft.com>
Subject:Hello There

The message response text is localized into the language specified by the http://schemas.microsoft.com/cdo/configuration/languagecode configuration field.

The Forward method retains all the attachments from this message but does not set any recipients on the new message.

See Also

http://schemas.microsoft.com/cdo/configuration/languagecode Field

http://schemas.microsoft.com/cdo/configuration/usemessageresponsetext Field


GetInterface Method

Returns the specified dual interface on the object.

[Visual Basic]
Function GetInterface(ByVal Interface as String) as Object
[C++]
HRESULT GetInterface(BSTR Interface, IDispatch** pVal);
[IDL]
HRESULT GetInterface([in] BSTR Interface, [out,retval] IDispatch** pVal);
Interface
The name of the interface to obtain.

Remarks

The GetInterface method is primarily intended as a generic interface navigation aid to scripting languages that do not support such navigation directly. Most COM classes that provide implementations of the IMessage interface expose additional dual interfaces that are accessible by scripting languages only through properties on the interface, such as BodyPart and DataSource, or through the GetInterface method. When properties do not exist on the interface to return these interfaces, the GetInterface method must be used.

The list of valid interface names to pass to GetInterface is dependent upon a specific implementation. As a general rule, the name of the desired interface should match the physical name of the interface as it appears in the type library or .idl file. Check the appropriate COM class for a list of exposed dual interfaces.

Example

The following example in VBScript demonstrates using GetInterface to return other interfaces on a Message object.

VBScript

'Dim iMessage
Set iMessage = CreateObject("CDO.Message")
' create an instance...get IMessage (IDispatch) back
Set iDataSource = iMessage.GetInterface("IDataSource")
' get IDataSource on the Message Object
Set iBodyPart = iMessage.GetInterface("IBodyPart")
' get IBodyPart on the Message Object

JScript

var iMsg = new ActiveXObject("CDO.Message");
var iDsrc = iMsg.GetInterface("IDataSource");
var iBp   = iMsg.GetInterface("IBodyPart");


GetStream Method

The GetStream method returns this message in serialized (wire-transport) format in an ADO Stream object.

[Visual Basic]
Function GetStream() as ADODB.Stream
[C++]
HRESULT GetStream(_Stream** pVal);
[IDL]
HRESULT GetStream([out,retval] _Stream** pVal);

Remarks

The GetStream method returns the entire message, including its headers and content (all body parts if MIME formatted) as a serialized stream within a single ADO Stream object. To obtain a stream for one of a message's body parts, call that body part object's GetDecodedContentStream or GetEncodedContentStream method.

The stream returned by this method is essentially a serialized copy of the current message, as it existed when this method was invoked. All changes made to the Stream object are local, and the message itself is not updated until the stream is flushed back by calling the Flush method on the ADO Stream object.

Example

[C++]
/*
 You must have the following paths in your
 INCLUDE path.
 %CommonProgramFiles%\system\ado
 %CommonProgramFiles%\microsoft shared\cdo

*/
#ifndef _CORE_EXAMPLE_HEADERS_INCLUDED
#define _CORE_EXAMPLE_HEADERS_INCLUDED
#import <msado15.dll> no_namespace
#import <cdoex.dll> no_namespace
#include <iostream.h>
#endif

void IMessage_GetStream_Example() {

   IMessagePtr Msg(__uuidof(Message));

   Msg->To      = "someone@microsoft.com";
   Msg->From    = "another@microsoft.com";
   Msg->Subject = "This is the subject";
   Msg->AddAttachment("c:\\myimage.gif","","");
   // Save the message stream to disk.
   Msg->GetStream()->SaveToFile("c:\\message.eml", adSaveCreateOverWrite );

}


Post Method

The Post method posts this message to the specified newsgroups.

[Visual Basic]
Sub Post()
[C++]
HRESULT Post();
[IDL]
HRESULT Post();

Remarks

How the message is posted depends upon the current configuration that is defined in the associated Configuration object. Consult a specific COM class implementation for a list of configuration settings used when posting messages.

The Post method does not invalidate this message after submitting it.

See Also

IMessage.Configuration, http://schemas.microsoft.com/cdo/configuration/postusing, http://schemas.microsoft.com/cdo/configuration/postusername, http://schemas.microsoft.com/cdo/configuration/postpassword


PostReply Method

The PostReply method creates and returns another message that can be used to post a reply to this message.

[Visual Basic]
Function PostReply() as CDO.Message
[C++]
HRESULT PostReply(IMessage** pVal);
[IDL]
HRESULT PostReply([out,retval] IMessage** pVal);

Remarks

The PostReply method retains all the newsgroups from this message in the Newsgroups property of the new message, but removes any attachments.

If the configuration field http://schemas.microsoft.com/cdo/configuration/usemessageresponsetext is set to True (VARIANT_TRUE), then the original message is formatted using the following:

-----Original Message-----
From:"Person" <person@microsoft.com>
Sent:Tue, 23 Mar 1998 12:41:37 -0800
To:"Person A" <personA@microsoft.com>
Subject:Hello There

The message response text is localized into the language specified by the http://schemas.microsoft.com/cdo/configuration/languagecode configuration field.

See Also

http://schemas.microsoft.com/cdo/configuration/languagecode Field, http://schemas.microsoft.com/cdo/configuration/usemessageresponsetext Field, IMessage.Configuration, http://schemas.microsoft.com/cdo/configuration/postusing, http://schemas.microsoft.com/cdo/configuration/postusername, http://schemas.microsoft.com/cdo/configuration/postpassword


Reply Method

The Reply method creates and returns another message that can be used to reply to the sender of this message.

[Visual Basic]
Function Reply() as CDO.Message
[C++]
HRESULT Reply(IMessage** pVal);
[IDL]
HRESULT Reply([out,retval] IMessage** pVal);

Remarks

The Reply method puts the sender of this message in the To property of the new message but removes all other recipients and any attachments. The To property is normally set from this message's From property, but if ReplyTo is set on this message, it is used instead.

If the configuration field http://schemas.microsoft.com/cdo/configuration/usemessageresponsetext is set to True (VARIANT_TRUE), then the original message is formatted using the following:

-----Original Message-----
From:"Person" <person@microsoft.com>
Sent:Tue, 23 Mar 1998 12:41:37 -0800
To:"Person A" <personA@microsoft.com>
Subject:Hello There

The message response text is localized into the language specified by the http://schemas.microsoft.com/cdo/configuration/languagecode configuration field.

See Also

http://schemas.microsoft.com/cdo/configuration/languagecode Field

http://schemas.microsoft.com/cdo/configuration/usemessageresponsetext Field

IMessage.Configuration, http://schemas.microsoft.com/cdo/configuration/sendusing, http://schemas.microsoft.com/cdo/configuration/sendusername, http://schemas.microsoft.com/cdo/configuration/sendpassword


ReplyAll Method

The ReplyAll method creates and returns another message that can be used to reply to the sender and all recipients.

[Visual Basic]
Function ReplyAll() as CDO.Message
[C++]
HRESULT ReplyAll(IMessage** pVal);
[IDL]
HRESULT ReplyAll([out,retval] IMessage** pVal);

Remarks

The ReplyAll method puts the sender of this message in the To property of the new message and retains all other recipients in the appropriate To, CC, and BCC properties, but removes any attachments. The To property is normally set from this message's From property, but if ReplyTo is set on this message, it is used instead.

If the configuration field http://schemas.microsoft.com/cdo/configuration/usemessageresponsetext is set to True (VARIANT_TRUE), then the original message is formatted using the following:

-----Original Message-----
From:"Person" <person@microsoft.com>
Sent:Tue, 23 Mar 1998 12:41:37 -0800
To:"Person A" <personA@microsoft.com>
Subject:Hello There

The message response text is localized into the language specified by the http://schemas.microsoft.com/cdo/configuration/languagecode configuration field.

If the the configuration field http://schemas.microsoft.com/cdo/configuration/sendemailaddress is set to an e-mail address found in the To or CC lines of the original message, that recipient is removed from the reply message (the person replying to the message will not be a recipient of the reply).

See Also

http://schemas.microsoft.com/cdo/configuration/languagecode Field, http://schemas.microsoft.com/cdo/configuration/usemessageresponsetext Field, IMessage.Configuration, http://schemas.microsoft.com/cdo/configuration/sendusing, http://schemas.microsoft.com/cdo/configuration/sendusername, http://schemas.microsoft.com/cdo/configuration/sendpassword


Send Method

The Send method sends the message.

[Visual Basic]
Sub Send()
[C++]
HRESULT Send();
[IDL]
HRESULT Send();

Remarks

How the message is sent depends upon the current configuration. The configuration is defined in the associated Configuration object that is referenced by the Configuration property on this interface. Consult a specific COM class implementation for a list of configuration settings used when sending messages.

The message must have at least one recipient, whether in the To, CC, or BCC property, before it can be successfully sent.

The Send method does not invalidate this message after submitting it. If you wish to invalidate it and release the memory, you should release all outstanding references to the implementing object in the standard way.

Example

Dim iMsg As New CDO.Message
Dim iConf As New CDO.Configuration
Dim Flds As ADODB.Fields
Set Flds = iConf.Fields
Flds(cdoSendUsingMethod) = cdoSendUsingPort
Flds(cdoSMTPServer) = "server"
Flds.Update

With iMsg
 Set .Configuration = iConf
     .MimeFormatted = False
     .AutoGenerateTextBody = False
     .To = "WhoKnows@microsoft.com"
     .Subject = "A short message"
     .TextBody = "Text of this short message."
     .Send
End With

See Also

IMessage.Configuration, http://schemas.microsoft.com/cdo/configuration/sendusing, http://schemas.microsoft.com/cdo/configuration/sendusername, http://schemas.microsoft.com/cdo/configuration/sendpassword


IMessages Interface

The IMessages interface defines methods and properties used to access a collection of Message objects retrieved by a call to IDropDirectory.GetMessages.

Note Because IMessages is only used for accessing messages on a file system, it is not useful in CDO for Microsoft® Exchange 2000 where messages are saved in the Microsoft Web Storage System.

IID
CD000025-8B95-11D1-82DB-00C04FB1625D
Extends
IDispatch

Member Summary

Properties

Name | Type | Description
Count (Read-Only) | [Visual Basic] Long [C++] long | Returns the number of Message objects contained in the collection.
Item (Read-Only) | [Visual Basic] IMessage [C++] IMessage* | Returns an IMessage interface on the Message object specified.
Filename (Read-Only) | [Visual Basic] String [C++] BSTR | Returns the name of the file in which a particular message is stored in serialized format on the file system.
_NewEnum (Read-Only) | [Visual Basic] N/A [C++] IUnknown* | Returns an IEnumVariant interface on an object that can be used to enumerate the collection. This is automatic in Microsoft® Visual Basic® For Each In constructs.

Methods

Name | Description
Delete | Deletes the specified Message object and the associated file from which the object was derived.
DeleteAll | Deletes all Message objects in the collection and all associated files on the file system.

Remarks

The IDropDirectory.GetMessages method is used to return a collection of messages from a specified file system directory. The object reference returned by this method is of type IMessages. You can use this object to manage the collection of messages returned. You can get the total count of Message objects in the collection, retrieve one of the messages using the IMessages.Item method, and get the name of the file housing the message on the file system using the IMessages.Filename property.

Example

This hypothetical example demonstrates how you could use the DropDirectory object (exposing the IDropDirectory interface) to enumerate the messages in the SMTP default drop directory and then copy each message addressed to a particular local account into an appropriate account mailbox directory. For example, you could have the local Administrator account's personal mail directory in the "c:\mailboxes\administrator" directory.

[Visual Basic]
Dim iDropDir as New CDO.DropDirectory
Dim iMsgs as CDO.IMessages
Dim iMsg as CDO.Message
Dim iStream as ADODB.Stream

Dim strTo as String
Dim ToRecipients as Variant
Dim strEmailName as String
Dim strAccountName as String
Dim strFileName as String
Dim strMailboxDir as String

Set iMsgs = iDropDir.GetMessages

For Each iMsg in iMsgs
  strFileName = iMsgs.FileName(iMsg)

  ' trim to get the short file name
  ' from the full path
  strFileName = Right(strFileName, Len(strFileName) - InStrRev(strFileName,"\") )

  ' Get the To recipients...and assume they are all local accounts
  strTo = iMsg.To
  ToRecipients = Split(strTo,",")
  Dim j, lpos, rpos, posdiff
  ' loop through recipients and get account names for each
  ' Each address will be in either the "Name" <name@tld> or
  '  simply <name@tld>
  ' We get the account name by getting the string
  ' between "<" and "@"
  For j = LBound(ToRecipients) to UBound(ToRecipients)
    strEmailName = ToRecipients(j)
    lpos = InStr(strEmailName,"<")
    rpos = InStr(strEmailName,"@")
    posdiff = rpos - lpos - 1
    strAccountName = Mid(strEmailName,lpos + 1, posdiff)

    ' For the purposes of this example,
    ' each account's mailbox directory resides in the
    ' directory c:\mailboxes. For user Joe, their account
    ' directory would be c:\mailboxes\joe
    strMailboxDir = "c:\mailboxes\" & strAccountName
    ' Get the message stream
    Set iStream = iMsg.GetStream

    ' write the stream to the user's mailbox directory
    ' the file name is the same as the one in the drop directory
    iStream.SaveToFile strMailboxDir & "\" & strFileName
    iStream.Close
    Set iStream = Nothing
  Next j
Next iMsg

' once we're done, delete the picked up messages
' this deletes the files from the file system as well.
iMsgs.DeleteAll

Set iMsgs = Nothing
Set iDropDir = Nothing
[C++,IDL]
#import "d:\program files\common files\system\ado\msado15.dll" no_namespace raw_interfaces_only
#import <cdosys.dll> no_namespace raw_interfaces_only
#include <iostream.h>
#include <assert.h>
#include <wchar.h>

void main(int argc, char* argv[])
{
  CoInitialize(NULL);

  IDropDirectory* pDropDir = NULL;
  IMessages*      pMsgs    = NULL;
  IUnknown*       pUnk     = NULL;
  IEnumVARIANT*   pEnum    = NULL;

  CoCreateInstance(
                  __uuidof(DropDirectory),
                  NULL,
                  CLSCTX_SERVER,
                  __uuidof(IDropDirectory),
                  (void**)&pDropDir));

  pDropDir->GetMessages(L"",&pMsgs);
  long count = 0;
  pMsgs->get_Count(&count);
  cout << count << endl;

   pMsgs->get__NewEnum(&pUnk);
   pUnk->QueryInterface(__uuidof(IEnumVARIANT),(void**)&pEnum);

   ULONG cFetched = 0;
   VARIANT var;
   VariantInit(&var);
   while (1) {
      cFetched = 0;
      pEnum->Next(1,&var,&cFetched);
      cout << "fetched: " << cFetched << endl;
      if(cFetched == 0)
         break;
      assert(var.vt == VT_DISPATCH);
      IMessage* pMsg = NULL;

       var.pdispVal->QueryInterface(__uuidof(IMessage),(void**)&pMsg);
       var.pdispVal->Release();
       VariantClear(&var);
       VARIANT varIntf;
       VariantInit(&varIntf);
       V_VT(&varIntf) = VT_DISPATCH;
       varIntf.pdispVal = pMsg;
       varIntf.pdispVal->AddRef();
       BSTR szFilename;
       pMsgs->get_FileName(varIntf,&szFilename);
       VariantClear(&varIntf);

       cout << _bstr_t(szFilename) << endl;
       wchar_t* pwchar;
       pwchar = wcsrchr(szFilename,'\\');
       _bstr_t mailfilename(pwchar+1);
       BSTR to;
       pMsg->get_To(&to);
       wchar_t* pWChar = to;

       wchar_t szbuffer[100];
       wchar_t lt = '<';
       wchar_t amp = '@';
       wchar_t* pFirst;
       unsigned int curPos = 0;
       _bstr_t mailboxesroot = "c:\\mailboxes\\";

       for(unsigned int k = 0;k<wcslen(pWChar);k++){
          if(pWChar[k] == lt) {
          pFirst = &pWChar[k];
          curPos = k;
       }
       if(pWChar[k] == amp) {
          cout << "amp" << endl;
          wcsncpy(szbuffer,pFirst+1,k-curPos-1);
          buffer[k-curPos-1] = (wchar_t)'\0';
         _bstr_t filen = mailboxesroot + _bstr_t(buffer) + "\\" + _bstr_t(mailfilename);
         _Stream* pStrm = NULL;
         pMsg->GetStream(&pStrm);
         pStrm->SaveToFile(filen,adSaveCreateOverWrite);
         pStrm->Release();
     }
   }
   pMsg->Release();

  }

  CoUninitialize();
}


Count Property

Returns the number of Message objects contained in the collection.

[Visual Basic]
Property Count as Long
read-only
[C++]
HRESULT get_Count(long* pVal);
[IDL]
HRESULT [propget] Count([out,retval] long* pVal);

Remarks

The Count property returns the number of objects in the collection. The indexes for the objects in the collection range from 1 to Count.

The collection is not automatically updated when new messages arrive in the directory used to retrieve the Messages collection. Count only returns the number of Message objects currently in the collection, and not the number of messages that actually reside on the file system at any given time. To update the collection, you need to call IDropDirectory.GetMessages again and thus retrieve a new collection.

Example

[Visual Basic]
Dim iDropDir as New CDO.DropDirectory
Dim iMsgs as CDO.IMessages
Dim iMsg as CDO.Message
Dim i as Long
Dim C as Long
i = 1
Set iMsgs = iDropDir.GetMessages
C = iMsgs.Count
For i = 1 to C
  Set iMsg = iMsgs.Item(i)
  If iMsg.To = "someaddress" Then
   iMsgs.Delete i
  End If
Next i
[C++,IDL]
#import "d:\program files\common files\system\ado\msado15.dll" no_namespace raw_interfaces_only
#import <cdosys.dll> no_namespace raw_interfaces_only
#include <iostream.h>

void main(int argc, char* argv[])
{
  CoInitialize(NULL);

  IDropDirectory* pDropDir = NULL;
  IMessages* pMsgs         = NULL;
  IMessage* pMsg           = NULL;
 CoCreateInstance(
          __uuidof(DropDirectory),
          NULL,
          CLSCTX_SERVER,
          __uuidof(IDropDirectory),
          (void**)&pDropDir));

  pDropDir->GetMessages(L"",&pMsgs);
  long count = 0;
  pMsgs->get_Count(&count);
  cout << count << endl;
  for(long i = 1;i<=count;i++) {
      pMsgs->get_Item(i,pMsg));
      BSTR szTo;
      pMsg->get_To(&szTo);
      if(_bstr_t(szTo) == _bstr_t("someaddress"))
          pMsgs->Delete(_variant_t((long)i));
      SysFreeString(szTo);
   }

  CoUninitialize();
}


Item Property

Returns the specified Message object from the collection.

[Visual Basic]
Property Item(Index as Long) as CDO.Message
read-only
[C++]
HRESULT get_Item(long Index, IMessage** ppMessage);
[IDL]
HRESULT [propget] Item(long Index, [out,retval] IMessage** ppMessage);
Index
The ordinal index of the Message object to retrieve.

Remarks

The Item property is intended for use with For loops, or to retrieve a specific Message object in the collection. If you simply want to enumerate the collection, you can use the IMessages._NewEnum property in the standard way. With Microsoft® Visual Basic®, use of this property is automatic within For Each In constructs.


FileName Property

Returns the name of the file containing the message on the file system.

[Visual Basic]
Property FileName(Var as Variant) as String
read-only
[C++]
HRESULT get_FileName(VARIANT var, BSTR* Filename)
[IDL]
HRESULT [propget] FileName([in] VARIANT var, [out,retval] BSTR* Filename);
var
The ordinal index or IMessage interface of the object for which you are requesting the file name.
Filename
On return, the full path to the file from which the specified Message object was created. The Filename is the logical result when getting the property in languages such as Visual Basic.

Remarks

You can identify the message for which you want the file name using the first argument to the property. You can either specify the ordinal index of the Message object or pass the IMessage object reference itself.

One common use of the FileName property is when you want to modify the contents of the messages stored in a particular directory and save the changes back into the file from which each Message object was derived. When you retrieve a Messages collection, each Message object in the collection is created using the serialized message stream stored in a file with the .eml extension. For these messages, unlike messages stored in the Microsoft Exchange store, you cannot use the IDataSource interface on the Message object to bind to the file, call IDataSource.Save, and thereby save the modified message contents back to the file. In such cases, you must use an ADO Stream object or some other means, such as a Scripting.FileSystemObject object, to save the new message contents back to the file system. You can use the FileName property to get the file name, and then overwrite the file with the new contents of the message. You can use the IMessage.GetStream method to return the contents of the Message object in serialized format within an ADO Stream object. The _Stream interface defines the _Stream.SaveToFile method that can be used to save the stream to disk. The following example demonstrates how to do this.

Example

This example appends text to the end of each text/plain body part of each message in the SMTP drop directory, and then saves the modified message back into the file from which the Message object was derived.

[Visual Basic]
Dim iDropDir as New CDO.DropDirectory
Dim iMsgs as CDO.IMessages
Dim iMsg as CDO.Message
Dim iStream as ADODB.Stream
Dim fileName as String
Dim TxtBody as String

Set iMsgs = iDropDir .GetMessages
For Each iMsg in iMsgs
  TxtBody = ""
  fileName = ""
  fileName = iMsgs.FileName(iMsg)
  TxtBody = iMsg.TextBody
  TxtBody = TxtBody & vbCrLf & vbCrLf & "Here is some appended text"
  iMsg.TextBody = TxtBody
  Set iStream = iMsg.GetStream
  iStream.SaveToFile fileName, adSaveCreateOverWrite
Next iMsg
[C++,IDL]
#import "d:\program files\common files\system\ado\msado15.dll" no_namespace raw_interfaces_only
#import <cdosys.dll> no_namespace raw_interfaces_only
#include <iostream.h>

void main(int argc, char* argv[])
{
  CoInitialize(NULL);

  IDropDirectory* pDropDir = NULL;
  IMessages* pMsgs = NULL;
  IUnknown* pUnk = NULL;
  IEnumVARIANT* pEnum = NULL;

  CoCreateInstance(
       __uuidof(DropDirectory),
       NULL,
       CLSCTX_SERVER,
       __uuidof(IDropDirectory),
      (void**)&pDropDir));

  pDropDir->GetMessages(L"",&pMsgs);
  long count = 0;
  pMsgs->get_Count(&count);
  cout << count << endl;

  pMsgs->get__NewEnum(&pUnk);
  pUnk->QueryInterface(__uuidof(IEnumVARIANT),(void**)&pEnum));

  ULONG cFetched = 0;
  VARIANT var;
  VariantInit(&var);
  while (1) {
    cFetched = 0;
      pEnum->Next(1,&var,&cFetched);
      cout << "fetched: " << cFetched << endl;
      if(cFetched == 0)
        break;
      IMessage* pMsg = NULL;
      var.pdispVal->QueryInterface(__uuidof(IMessage),(void**)&pMsg);
      var.pdispVal->Release();
      VariantClear(&var);

      // get file name
      BSTR szFilename;
      VARIANT varIntf;
      VariantInit(&varIntf);
      V_VT(&varIntf) = VT_DISPATCH;
      varIntf.pdispVal = pMsg;
      varIntf.pdispVal->AddRef();
      pMsgs->get_Filename(varIntf,&szFilename);

      // get text body of message
      BSTR szTxtBody;
      pMsg->get_TextBody(&szTxtBody);
      _bstr_t tempBody(szTxtBody);
      tempBody += "\r\n\r\nThis is some appended text";
      pMsg->put_TextBody(BSTR(tempBody);
      SysFreeString(szTxtBody);

      _Stream* pStrm = NULL;
      pMsg->GetStream(&pStrm);
      // write changes back to file
      pStrm->SaveToFile(szFilename,adSaveCreateOverWrite);
      pStrm->Release();
      SysFreeString(szFilename);
      pMsg->Release();
    }
  CoUninitialize();
}


NewEnum Property

Platform SDK: Exchange 2000 Server

_NewEnum Property

Returns an IEnumVARIANT interface on an object that can be used to enumerate the collection.

[Visual Basic]
(*Restricted from direct access. Used in For Each In constructs)
[C++]
HRESULT get__NewEnum(IUnknown** retval);
[IDL]
[propget, restricted, id(DISPID_NEWENUM)] HRESULT _NewEnum([out, retval] IUnknown** retval);
retval
On return, an IEnumVARIANT object reference that can be used to enumerate the collection.

Remarks

The _NewEnum property is marked restricted in the IDL definition for IMessages and is not shown in the Visual Basic object browser. It is automatically used internally when you use the For Each In construct in Visual Basic.

#import "c:\program files\common files\system\ado\msado15.dll" no_namespace raw_interfaces_only
#import <cdosys.dll> no_namespace raw_interfaces_only
#include <iostream.h>
void main()
{
  CoInitialize(NULL);
  IEnumVARIANT* pEnum = NULL;
  CoCreateInstance(
        __uuidof(DropDirectory),
        NULL,
        CLSCTX_SERVER,
        __uuidof(IDropDirectory),
        (void**)&pDropDir);

  pDropDir->GetMessages(L"",&pMsgs);
  long count = 0;
  pMsgs->get_Count(&count);
  cout << count << endl;

  pMsgs->get__NewEnum(&pUnk);
  pUnk->QueryInterface(__uuidof(IEnumVARIANT),(void**)&pEnum);

  ULONG cFetched = 0;
  VARIANT var;
  VariantInit(&var);
  while (1) {
    cFetched = 0;
    pEnum->Next(1,&var,&cFetched);
    cout << "fetched: " << cFetched << endl;
    if(cFetched == 0)
       break;
    IMessage* pMsg = NULL;

    var.pdispVal->QueryInterface(__uuidof(IMessage),(void**)&pMsg);
    var.pdispVal->Release();
    VariantClear(&var);
    BSTR to;
    pMsg->get_To(&to);
    cout << _bstr_t(to) << endl;
    SysFreeString(to);
    pMsg->Release();

  }
  CoUninitialize();
}


Delete Method

Deletes the specified Message object in the collection and from the file system.

[Visual Basic]
Sub Delete(Index as Long)
[C++]

HRESULT Delete( long Index )

[IDL]
HRESULT Delete(long Index);
Index
The ordinal index of the Message object to delete.

Remarks

You must pass the ordinal index of the object in the collection to delete. You cannot pass an object reference.

You can use the Delete method within an enumeration successfully because the _NewEnum property returns an enumeration of the current collection in the same order as the ordinal index for each object.

The Delete method also deletes the file on the file system used to create the Message object.

Example

Dim iDropDir as New CDO.DropDirectory
Dim iMsgs as CDO.IMessages
Dim iMsg as CDO.Message
Dim i as Long
i = 1
Set iMsgs = iDropDir.GetMessages
For Each iMsg in iMsgs
  If iMsg.To = "someaddress" Then
   iMsgs.Delete i
  End If
  i = i + 1
Next iMsg
© 2000-2001 Microsoft Corporation. All rights reserved.


DeleteAll Method

Deletes all Message objects in the collection along with all associated files on the file system.

[Visual Basic]
Sub DeleteAll()
[C++]
HRESULT DeleteAll();
[IDL]
HRESULT DeleteAll();

Remarks

The DeleteAll method deletes all Message objects in the collection. In addition, it deletes the file from which each Message object was derived.

Example

Dim iDropDir as New CDO.DropDirectory
Dim iMsgs as CDO.IMessages
Dim iMsg as CDO.Message

Set iMsgs = iDropDir.GetMessages

For Each iMsg in iMsgs
 ' process the message object
Next iMsg

' delete these when done. The associated files in the
' directory are deleted as well
iMsgs.DeleteAll


INNTPOnPost Interface

The INNTPOnPost interface defines the interface between event sinks written with CDO and the NNTP service OnPost event source.

IID
CD000027-8B95-11D1-82DB-00C04FB1625D
Extends
IDispatch

Member Summary

Method

Name | Description
OnPost | Called by the NNTP event source on bound OnPost event sinks when a message has arrived to the NNTP service.

Remarks

To implement an NNTP OnPost event sink using CDO, you create and register a local COM class that exposes the CDO INNTPOnPostFinal interface.

For more information on writing NNTP OnPost event sinks, see SMTP/NNTP Transport Event Sinks with CDO.

Example

[C++,IDL]

The following code is an example using the Active Template Library (ATL) to implement an NNTP OnPost event sink.

#include "StdAfx.h"
#include "sinkproj.h"  // contains guids for this class
#include "resource.h"
#import "c:\program files\common files\system\ado\msado15.dll" no_namespace
#import "c:\program files\common files\microsoft shared\cdo\cdoex.dll" raw_interfaces_only no_namespace
class ATL_NO_VTABLE CMyClass :
    public CComObjectRootEx<CComSingleThreadModel>,
    public CComCoClass<CMyClass,&CLSID_MyClass>,
    public IDispatchImpl<INNTPOnPost,&__uuidof(INNTPOnPost),&LIBID_MyClass>
{
public:
     CMyClass() {}
DECLARE_REGISTRY_RESOURCEID(IDR_MyClass)
DECLARE_NOT_AGGREGATABLE(CMyClass)

BEGIN_COM_MAP(CMyClass)
  COM_INTERFACE_ENTRY(INNTPOnPost)
  COM_INTERFACE_ENTRY(IDispatch)
END_COM_MAP()

// INNTPOnPost
public:
   STDMETHOD(OnPost) (/* in */ IMessage* pMsg, /* in,out */ CdoEventStatus* EventStatus);
private:
   // any other custom methods you wish to use

};

CMyClass::OnPost( IMessage* pMsg, CdoEventStatus* EventStatus)
{
   // TODO:  add sink code here
}
[Visual Basic]
' References to ADO 2.5 and CDO for Microsoft Exchange
Implements CDO.INNTPOnPost

Private Sub INNTPOnPost_OnPost( ByVal Msg as CDO.Message, EventStatus as CdoEventStatus )
  '  Add sink code here
End Sub
[VBScript]
<SCRIPT LANGUAGE="VBScript">
Sub INNTPOnPost_OnPost( ByVal Msg, EventStatus)
  ' Add sink code here
End Sub
</SCRIPT>

See Also

SMTP/NNTP Transport Event Sinks with CDO

INNTPOnPostEarly Interface

INNTPOnPostFinal Interface

© 2000-2001 Microsoft Corporation. All rights reserved.


OnPost Method

Called by the NNTP event source on bound OnPost event sinks when a message has arrived to the NNTP service.

[Visual Basic]
Sub OnPost(ByVal Msg as CDO.Message, EventStatus as CdoEventStatus)
[C++]
HRESULT OnPost(IMessage* Msg, CdoEventStatus* EventStatus);
[IDL]
HRESULT OnPost([in] IMessage* Msg, [in,out] CdoEventStatus* EventStatus);
Msg
An IMessage interface on a Message object holding the message that arrived.
EventStatus
On return, the status of the event. The event sink signals to the source whether to continue notifying subsequent event sinks of the event, or to stop and return. The CdoEventStatus enumeration in the type library defines enumerated values for this argument.

Remarks

The Message object contains the message in unexpanded format; the recipient addresses have not been resolved or expanded, and are thus still in the format in which the sending message transfer agent placed them in the message envelope. The sink cannot modify the contents of the posted message. The envelope fields, however, can be modified. For more information, see SMTP/NNTP Transport Event Sinks with CDO.

The OnPost event for the NNTP service is synchronous, meaning that the event dispatcher thread is blocked either for the duration of time required for all bound event sinks to be created (if necessary) and executed, or until a sink preemptively stops event notifications by returning the EventStatus parameter with the value cdoSkipRemainingSinks.

See Also

SMTP/NNTP Transport Event Sinks with CDO

INNTPOnPostEarly Interface

INNTPOnPostFinal Interface

© 2000-2001 Microsoft Corporation. All rights reserved.


INNTPOnPostEarly Interface

The INNTPOnPostEarly interface defines the interface between event sinks written with CDO and the NNTP service OnPostEarly event source.

IID
CD000033-8B95-11D1-82DB-00C04FB1625D
Extends
IDispatch

Member Summary

Method

Name | Description
OnPostEarly | Called by the NNTP event source on bound OnPostEarly event sinks when message or news feed headers arrive to the NNTP service but before the message content has arrived.

Remarks

To implement an NNTP OnPostEarly event sink using CDO, you create and register a local COM class that exposes the CDO INNTPOnPostEarly interface.

For more information on implementing NNTP OnPostEarly event sinks, see SMTP/NNTP Transport Event Sinks with CDO.

Example

[C++,IDL]

The following code is an example using the Active Template Library (ATL) to implement an NNTP OnPostEarly event sink.

#include "StdAfx.h"
#include "sinkproj.h"  // contains guids for this class
#include "resource.h"
#import "c:\program files\common files\system\ado\msado15.dll" no_namespace
#import "c:\program files\common files\microsoft shared\cdo\cdoex.dll" raw_interfaces_only no_namespace

class ATL_NO_VTABLE CMyClass :
    public CComObjectRootEx<CComSingleThreadModel>,
    public CComCoClass<CMyClass,&CLSID_MyClass>,
    public IDispatchImpl<INNTPOnPostEarly,&__uuidof(INNTPOnPostEarly),&LIBID_MyClass>
{
public:
     CMyClass() {}
DECLARE_REGISTRY_RESOURCEID(IDR_MyClass)
DECLARE_NOT_AGGREGATABLE(CMyClass)

BEGIN_COM_MAP(CMyClass)
  COM_INTERFACE_ENTRY(INNTPOnPostEarly)
  COM_INTERFACE_ENTRY(IDispatch)
END_COM_MAP()

// INNTPOnPostEarly
public:
   STDMETHOD(OnPostEarly) (/* in */ IMessage* pMsg, /* in,out */ CdoEventStatus* EventStatus);
private:
   // any other custom methods you wish to use

};

CMyClass::OnPostEarly( IMessage* pMsg, CdoEventStatus* EventStatus)
{
   // TODO:  add sink code here
}
[Visual Basic]
' References to ADO 2.5 and CDO for Microsoft Exchange
Implements CDO.INNTPOnPostEarly

Private Sub INNTPOnPostEarly_OnPostEarly( ByVal Msg as IMessage,  EventStatus as CdoEventStatus )
  '  Add handling code here
End Sub
[VBScript]
<SCRIPT LANGUAGE="VBScript">
Sub INNTPOnPostEarly_OnPostEarly( ByVal Msg, EventStatus)
  ' Add sink code here
End Sub
</SCRIPT>

See Also

SMTP/NNTP Transport Event Sinks with _CDO

INNTPOnPost Interface

INNTPOnPostFinal Interface

© 2000-2001 Microsoft Corporation. All rights reserved.


OnPostEarly Method

Called by the NNTP event source on bound OnPostEarly event sinks when message or news feed headers arrive to the NNTP service but before the message content has arrived.

[Visual Basic]
Sub OnPostEarly(ByVal Msg as CDO.Message, EventStatus as CdoEventStatus)
[C++]
HRESULT OnPostEarly(IMessage* Msg, CdoEventStatus* EventStatus);
[IDL]
HRESULT OnPostEarly([in] IMessage* Msg, [in,out] CdoEventStatus* EventStatus);
Msg
An IMessage interface on a Message object holding the message headers and envelope fields that arrived.
EventStatus
On return, the status of the event. The event sink signals to the source whether to continue notifying subsequent event sinks of the event, or to stop and return. The CdoEventStatus enumeration in the type library defines enumerated values for this argument.

Remarks

For OnPostEarly events, the Message object accessible to each sink contains only envelope fields and message header fields; when this event fires, the body of the message has not yet arrived. You can access the envelope fields for the message using the IMessage.EnvelopeFields collection. You can access the message headers using properties on the IMessage interface, such as IMessage.Newsgroups, or using the IMessage.Fields collection. The message headers are read-only, but the envelope fields can be modified.

The OnPostEarly event for the NNTP service is synchronous, meaning that the event dispatcher thread is blocked either for the duration of time required for all bound event sinks to be created (if necessary) and executed, or until a sink preemptively stops event notifications by returning the EventStatus parameter with the value cdoSkipRemainingSinks.

See Also

SMTP/NNTP Transport Event Sinks with CDO

INNTPOnPost Interface

INNTPOnPostFinal Interface

IMessage Interface

CdoEventStatus Enum

© 2000-2001 Microsoft Corporation. All rights reserved.


INNTPOnPostFinal Interface

The INNTPOnPostFinal interface defines the interface between event sinks written with CDO and the NNTP service OnPostFinal event source.

IID
CD000028-8B95-11D1-82DB-00C04FB1625D
Extends
IDispatch

Member Summary

Method

Name | Description
OnPostFinal | Called by the NNTP event source on bound OnPostFinal event sinks after a message or news feed has been posted by the NNTP service.

Remarks

To implement an NNTP OnPostFinal event sink using CDO, you create and register a local COM class that exposes the CDO INNTPOnPostFinal interface.

For more information on writing NNTP OnPostFinal event sinks, see SMTP/NNTP Transport Event Sinks_with_CDO.

Example

[C++,IDL]

The following code is an example using the Active Template Library (ATL) to implement an NNTP OnPostFinal event sink.

#include "StdAfx.h"
#include "sinkproj.h"  // #include "resource.h"
#import "c:\program files\common files\system\ado\msado15.dll" raw_interfaces_only no_namespace
#import "c:\program files\common files\microsoft shared\cdo\cdoex.dll" raw_interfaces_only no_namespace
class ATL_NO_VTABLE CMyClass :
    public CComObjectRootEx<CComSingleThreadModel>,
    public CComCoClass<CMyClass,&CLSID_MyClass>,
    public IDispatchImpl<INNTPOnPostFinal,&__uuidof(INNTPOnPostFinal),&LIBID_MyClass>
{
public:
     CMyClass() {}
DECLARE_REGISTRY_RESOURCEID(IDR_MyClass)
DECLARE_NOT_AGGREGATABLE(CMyClass)

BEGIN_COM_MAP(CMyClass)
  COM_INTERFACE_ENTRY(INNTPOnPostFinal)
  COM_INTERFACE_ENTRY(IDispatch)
END_COM_MAP()

// INNTPOnPostFinal
public:
   STDMETHOD(OnPostFinal) (/* in */ IMessage* pMsg, /* in,out */ CdoEventStatus* EventStatus);
private:
   // any other custom methods you wish to use

};

CMyClass::OnPostFinal( IMessage* pMsg, CdoEventStatus* EventStatus)
{
   // TODO:  add sink code here
}
[Visual Basic]
' References to ADO 2.5 and CDO for Microsoft Exchange
Implements CDO.INNTPOnPostFinal

Public Sub INNTPOnPostFinal_OnPostFinal( ByVal Msg as CDO.Message,  EventStatus as CdoEventStatus )
  REM  Add sink code here
End Sub
[VBScript]
<SCRIPT LANGUAGE="VBScript">
Sub INNTPOnPostFinal_OnPostFinal( Msg, EventStatus )
  ' code here
End Sub
</SCRIPT>

See Also

SMTP/NNTP Transport Event Sinks with CDO

INNTPOnPost Interface

INNTPOnPostEarly Interface

IMessage Interface

© 2000-2001 Microsoft Corporation. All rights reserved.


OnPostFinal Method

Called by the NNTP event source on bound OnPostFinal event sinks after a message or news feed has been posted by the NNTP service.

[Visual Basic]
Sub OnPostFinal(ByVal Msg as CDO.Message, EventStatus as CdoEventStatus)
[C++]
HRESULT OnPostFinal(IMessage* Msg, CdoEventStatus* EventStatus);
[IDL]
HRESULT OnPostFinal([in] IMessage* Msg, [in,out] CdoEventStatus* EventStatus);
Msg
The IMessage interface on a Message object holding the message that arrived.
EventStatus
On return, the status of the event. The event sink signals to the source whether to continue notifying subsequent event sinks, or to stop and return. The CdoEventStatus enumeration in the type library contains the enumerated values for this argument.

Remarks

The OnPostFinal event for the NNTP service is synchronous, meaning that the event dispatcher thread is blocked for either the duration of time required for all bound event sinks to be created (if necessary) and executed, or until a sink preemptively stops event notifications by returning the EventStatus parameter with the value cdoSkipRemainingSinks.

See Also

SMTP/NNTP Transport Event Sinks with CDO

INNTPOnPost Interface

INNTPOnPostEarly Interface

CdoEventStatus Enum

IMessage Interface

© 2000-2001 Microsoft Corporation. All rights reserved.


IPerson Interface

Manage a contact who may have an Exchange Server mailbox.

IID
CD000127-8B95-11D1-82DB-00C04FB1625D
Extends
IDispatch

Member Summary

Properties

Name | Type | Description
Company | [Visual Basic,VBScript] String [C++,IDL] BSTR | Contains the company name of the person contact.
Configuration | IConfiguration IConfiguration* | A reference to a Configuration object that defines the configuration information used by the object.
DataSource (Read-Only) | IDataSource [C++,IDL] IDataSource* | Returns the IDataSource interface on the object.
Email | [Visual Basic,VBScript] String [C++,IDL] BSTR | Contains the primary e-mail address of the person contact.
Email2 | [Visual Basic,VBScript] String [C++,IDL] BSTR | Contains the secondary e-mail address of the person contact.
Email3 | [Visual Basic,VBScript] String [C++,IDL] BSTR | Contains the tertiary e-mail address of the person contact.
EmailAddresses | [Visual Basic,VBScript] Variant [C++,IDL] BSTR | Contains a list of valid e-mail addresses of the person contact.
Fields (Read-Only) | [Visual Basic,VBScript] Fields [C++,IDL] Fields* | Returns the ADO Fields object for the person contact.
FileAs | [Visual Basic,VBScript] String [C++,IDL] BSTR | Defines how to display the person contact.
FileAsMapping | [Visual Basic,VBScript] String [C++,IDL] BSTR | Defines how to construct what is displayed for the person contact.
FirstName | [Visual Basic,VBScript] String [C++,IDL] BSTR | Contains the first name of the person contact.
HomeCity | [Visual Basic,VBScript] String [C++,IDL] BSTR | Contains the name of the home city for the person contact.
HomeCountry | [Visual Basic,VBScript] String [C++,IDL] BSTR | Contains the name of the home country/region for the person contact.
HomeFax | [Visual Basic,VBScript] String [C++,IDL] BSTR | Contains the home fax number for the person contact.
HomePhone | [Visual Basic,VBScript] String [C++,IDL] BSTR | Contains the home telephone number for the person contact.
HomePostalAddress (Read-only) | [Visual Basic,VBScript] String [C++,IDL] BSTR | Contains the home postal address street number for the person contact.
HomePostalCode | [Visual Basic,VBScript] String [C++,IDL] BSTR | Contains the home postal code (zip code in the US) for the person contact.
HomePostOfficeBox | [Visual Basic,VBScript] String [C++,IDL] BSTR | Contains the post office box number for the person contact.
HomeState | [Visual Basic,VBScript] String [C++,IDL] BSTR | Contains the home state for the person contact.
HomeStreet | [Visual Basic,VBScript] String [C++,IDL] BSTR | Contains the home street for the person contact.
Initials | [Visual Basic,VBScript] String [C++,IDL] BSTR | Contains the initials of the person contact.
LastName | [Visual Basic,VBScript] String [C++,IDL] BSTR | Contains the last name of the person contact.
MailingAddress | [Visual Basic,VBScript] String [C++,IDL] BSTR | Contains the postal mailing address for the person contact.
MailingAddressID | [Visual Basic,VBScript] String [C++,IDL] BSTR | Identifies which address is the mailing address for the person contact.
MiddleName | [Visual Basic,VBScript] String [C++,IDL] BSTR | Contains the middle name of the person contact.
MobilePhone | [Visual Basic,VBScript] String [C++,IDL] BSTR | Contains the mobile telephone number for the person contact.
NamePrefix | [Visual Basic,VBScript] String [C++,IDL] BSTR | Contains the title to precede the name of the person contact.
NameSuffix | [Visual Basic,VBScript] String [C++,IDL] BSTR | Contains the title to follow the name of the person contact.
Title | [Visual Basic,VBScript] String [C++,IDL] BSTR | Contains the job title for the person contact.
WorkCity | [Visual Basic,VBScript] String [C++,IDL] BSTR | Contains the work city for the person contact.
WorkCountry | [Visual Basic,VBScript] String [C++,IDL] BSTR | Contains the work country/region for the person contact.
WorkFax | [Visual Basic,VBScript] String [C++,IDL] BSTR | Contains the work fax number for the person contact.
WorkPager | [Visual Basic,VBScript] String [C++,IDL] BSTR | Contains the work pager number for the person contact.
WorkPhone | [Visual Basic,VBScript] String [C++,IDL] BSTR | Contains the work telephone number for the person contact.
WorkPostalAddress | [Visual Basic,VBScript] String [C++,IDL] BSTR | Contains the work postal address street number for the person contact.
WorkPostalCode | [Visual Basic,VBScript] String [C++,IDL] BSTR | Contains the work postal code (zip code in the US) for the person contact.
WorkPostOfficeBox | [Visual Basic,VBScript] String [C++,IDL] BSTR | Contains the work post office box number for the person contact.
WorkState | [Visual Basic,VBScript] String [C++,IDL] BSTR | Contains the work state for the person contact.
WorkStreet | [Visual Basic,VBScript] String [C++,IDL] BSTR | Contains the work street for the person contact.

Methods

Name | Description
GetInterface | Returns the specified interface on the person contact. Acts as a QueryInterface or Set method for script languages.
GetvCardStream | Obtains a vCard Stream object on the person contact.

Remarks

Use the IPerson interface to create an individual contact. Contacts are different from recipients since contacts do not appear in an address book.

If you regularly send mail to an individual, you should create an address entry for that individual using the IAddressee.

Example

[Visual Basic]
Dim p As New CDO.Person
p.DataSource.Open (addr, Nothing)
Dim MB As CDO.IMailbox
Dim myContacts As CDO.Folder

' Bind Mailbox to user's URL
p.DataSource.Open ("mailto:Someone@Somewhere.microsoft.com", Nothing)

' Set some properties for the contact
p.FirstName = "Some"
p.LastName = "One"
p.WorkStreet = "One Microsoft Way"
p.WorkCity = "Redmond"
p.WorkState = "WA"
p.Email = "SomeoneElse@SomewhereElse.microsoft.com"
p.WorkPhone = "425-882-8080"

' Get IMailbox IF on person
MB = p
myContacts = MB.Contacts

' Now save the new contact in the contacts folder
p.DataSource.SaveTo (myContacts.DataSource.SourceURL, Nothing)


Company Property

Contains the Company name for the person contact.

[Visual Basic, VBScript]
Property Company as String
[C++]
HRESULT get_Company(BSTR* pVal);
HRESULT put_Company(BSTR Val);
[IDL]
HRESULT [propget] Company([out,retval] BSTR* pVal);
HRESULT [proput] Company([in] BSTR Val);

Remarks

This property is also available as the urn:schemas:contacts:o field.


Configuration Property

Returns the IConfiguration interface on the person contact.

[Visual Basic, VBScript]
Property Configuration as IConfiguration
[C++]
HRESULT get_Configuration(IConfiguration** pVal);
HRESULT put_Configuration(IConfiguration* Val);
[IDL]
HRESULT [propget] Configuration([out,retval] IConfiguration** pVal);
HRESULT [proput] Configuration([in] IConfiguration* Val);


DataSource Property

Returns the IDataSource interface on the implementing object.

[Visual Basic, VBScript]
Property DataSource as IDataSource
Read-only
[C++]
HRESULT get_DataSource(IDataSource** pVal);
[IDL]
HRESULT [propget] DataSource([out,retval] IDataSource** pVal);

Remarks

This property returns the IDataSource interface on the implementing object. In CDO for Exchange Server, a common use of this property is to use the Open method on IDataSource to open an item in the store.

If the IDataSource interface is not implemented by the object, then the COM exception E_NOTIMPL is raised.


Email Property

Contains the primary e-mail address of the person contact.

[Visual Basic, VBScript]
Property Email as String
[C++]
HRESULT get_Email(BSTR* pVal);
HRESULT put_Email(BSTR Val);
[IDL]
HRESULT [propget] Email([out,retval] BSTR* pVal);
HRESULT [proput] Email([in] BSTR Val);

Remarks

This property is also available as the urn:schemas:contacts:email1 field.


Email2 Property

Contains the secondary e-mail address of the person contact.

[Visual Basic, VBScript]
Property Email2 as String
[C++]
HRESULT get_Email2(BSTR* pVal);
HRESULT put_Email2(BSTR Val);
[IDL]
HRESULT [propget] Email2([out,retval] BSTR* pVal);
HRESULT [proput] Email2([in] BSTR Val);

Remarks

This property is also available as the urn:schemas:contacts:email2 field.


Email3 Property

Contains the tertiary e-mail address of the person contact.

[Visual Basic, VBScript]
Property Email3 as String
[C++]
HRESULT get_Email3(BSTR* pVal);
HRESULT put_Email3(BSTR Val);
[IDL]
HRESULT [propget] Email3([out,retval] BSTR* pVal);
HRESULT [proput] Email3([in] BSTR Val);

Remarks

This property is also available as the urn:schemas:contacts:email3 field.


EmailAddresses Property

Contains a list of valid e-mail addresses of the person contact.

[Visual Basic, VBScript]
Property EmailAddresses as Variant
[C++]
HRESULT get_EmailAddresses(BSTR* pVal);
HRESULT put_EmailAddresses(BSTR Val);
[IDL]
HRESULT [propget] EmailAddresses([out,retval] BSTR* pVal);
HRESULT [proput] EmailAddresses([in] BSTR Val);

Remarks

This property is also available as the urn:schemas:contacts:proxyaddresses field.

When setting multiple e-mail addresses in this property, only one of them should have the SMTP prefix in uppercase—which designates the primary e-mail address. If no e-mail addresses has an uppercase SMTP, or all of them do, then no primary e-mail address is designated. If more than one e-mail address has an uppercase protocol, then the last e-mail address of each protocol will be considered the primary e-mail address for that protocol.


Fields Property

Returns the ADO Fields object for the person contact.

[Visual Basic, VBScript]
Property Fields as ADODB.Fields
Read-only
[C++]
HRESULT get_Fields(Fields** pVal);
[IDL]
HRESULT [propget] Fields([out,retval] Fields** pVal);

Remarks

The ADO Fields object is a collection of ADO Field objects that contain persistent information about the person contact. Each Field object holds a name/value pair defining an attribute for the person contact as stored in the Exchange schema. The name is always a string, and the value varies depending on the schema definition for the name. See the urn:schemas:contacts: namespace for information on contact properties.


FileAs Property

Defines how the contact is displayed in the folder view.

[Visual Basic, VBScript]
Property FileAs as String
[C++]
HRESULT get_FileAs(BSTR* pVal);
HRESULT put_FileAs(BSTR Val);
[IDL]
HRESULT [propget] FileAs([out,retval] BSTR* pVal);
HRESULT [proput] FileAs([in] BSTR Val);

Remarks

This property is also available as the urn:schemas:contacts:fileas field.

If this entry is null, the FileAsMapping property defines how the contact is displayed in the folder view. If this entry is not null, it contains the information that is displayed for the contact.

If you set a custom value to indicate how the contact will be displayed, this will set urn:schema:contact:fileasid to cdoMapToNone since the urn:schema:contacts:fileas value is not null.


FileAsMapping Property

Defines how to construct what is displayed for the person contact.

 [Visual Basic, VBScript]
Property FileAsMapping as CdoFileAsMappingID
[C++]
HRESULT get_FileAsMapping(CdoFileAsMappingID Val);
HRESULT put_FileAsMapping(CdoFileAsMappingID Val);
[IDL]
HRESULT [propget] FileAsMapping([out,retval] CdoFileAsMappingID Val);
HRESULT [proput] FileAsMapping([in] CdoFileAsMappingID Val);

Remarks

This property is also available as the urn:schemas:contacts:fileasid field.

If FileAs Property is explicitly set, then cdoMapToNone property is set. The values for this property are defined by the CdoFileAsMappingID enumeration.

If the FileAs property is null, the FileAsMapping property will define how the person’s contact name is constructed from other contact fields.


FirstName Property

Contains the first name of the person contact.

[Visual Basic, VBScript]
Property FirstName as String
[C++]
HRESULT get_FirstName(BSTR* pVal);
HRESULT put_FirstName(BSTR Val);
[IDL]
HRESULT [propget] FirstName([out,retval] BSTR* pVal);
HRESULT [proput] FirstName([in] BSTR Val);

Remarks

This property is also available as the urn:schemas:contacts:givenname field.


HomeCity Property

Contains the home city name of the person contact.

[Visual Basic, VBScript]
Property HomeCity as String
[C++]
HRESULT get_HomeCity(BSTR* pVal);
HRESULT put_HomeCity(BSTR Val);
[IDL]
HRESULT [propget] HomeCity([out,retval] BSTR* pVal);
HRESULT [proput] HomeCity([in] BSTR Val);

Remarks

This property is also available as the urn:schemas:contacts:homecity field.


HomeCountry Property

Contains the home country/region name of the person contact.

[Visual Basic, VBScript]
Property HomeCountry as String
[C++]
HRESULT get_HomeCountry(BSTR* pVal);
HRESULT put_HomeCountry(BSTR Val);
[IDL]
HRESULT [propget] HomeCountry([out,retval] BSTR* pVal);
HRESULT [proput] HomeCountry([in] BSTR Val);

Remarks

This property is also available as the urn:schemas:contacts:homecountry field.


HomeFax Property

Contains the home fax number of the person contact.

[Visual Basic, VBScript]
Property HomeFax as String
[C++]
HRESULT get_HomeFax(BSTR* pVal);
HRESULT put_HomeFax(BSTR Val);
[IDL]
HRESULT [propget] HomeFax([out,retval] BSTR* pVal);
HRESULT [proput] HomeFax([in] BSTR Val);

Remarks

This property is also available as the urn:schemas:contacts:homefax field.


HomePhone Property

Contains the home telephone number of the person contact.

[Visual Basic, VBScript]
Property HomePhone as String
[C++]
HRESULT get_HomePhone(BSTR* pVal);
HRESULT put_HomePhone(BSTR Val);
[IDL]
HRESULT [propget] HomePhone([out,retval] BSTR* pVal);
HRESULT [proput] HomePhone([in] BSTR Val);

Remarks

This property is also available as the urn:schemas:contacts:homephone field.


HomePostalAddress Property

Contains the home postal address street number of the person contact.

[Visual Basic, VBScript]
Property HomePostalAddress as String
Read-only
[C++]
HRESULT get_HomePostalAddress(BSTR* pVal);
[IDL]
HRESULT [propget] HomePostalAddress([out,retval] BSTR* pVal);

Remarks

This property is also available as the urn:schemas:contacts:homepostaladdress field.

This property is constructed from the other home properties. The CDO HomePostalAddress is constructed from the homestreet, homecity, homestate, and homepostalcode fields.

The HomePostalAddress in Directory Services (DS) can be read using ADO.


HomePostalCode Property

Contains the home postal code (zip code for US addresses) of the person contact.

[Visual Basic, VBScript]
Property HomePostalCode as String
[C++]
HRESULT get_HomePostalCode(BSTR* pVal);
HRESULT put_HomePostalCode(BSTR Val);
[IDL]
HRESULT [propget] HomePostalCode([out,retval] BSTR* pVal);
HRESULT [proput] HomePostalCode([in] BSTR Val);

Remarks

This property is also available as the urn:schemas:contacts:homepostalcode field.


HomePostOfficeBox Property

Contains the post office box number of the person contact.

[Visual Basic, VBScript]
Property HomePostfficeBox as String
[C++]
HRESULT get_HomePostOfficeBox(BSTR* pVal);
HRESULT put_HomePostOfficeBox(BSTR Val);
[IDL]
HRESULT [propget] HomePostOfficeBox([out,retval] BSTR* pVal);
HRESULT [proput] HomePostOfficeBox([in] BSTR Val);

Remarks

This property is also available as the urn:schemas:contacts:homepostofficebox field.


HomeState Property

Contains the home state of the person contact.

[Visual Basic, VBScript]
Property HomeState as String
[C++]
HRESULT get_HomeState(BSTR* pVal);
HRESULT put_HomeState(BSTR Val);
[IDL]
HRESULT [propget] HomeState([out,retval] BSTR* pVal);
HRESULT [proput] HomeState([in] BSTR Val);

Remarks

This property is also available as the urn:schemas:contacts:homestate field.


HomeStreet Property

Contains the home street of the person contact.

[Visual Basic, VBScript]
Property HomeStreet as String
[C++]
HRESULT get_HomeStreet(BSTR* pVal);
HRESULT put_HomeHomeStreet(BSTR Val);
[IDL]
HRESULT [propget] HomeStreet([out,retval] BSTR* pVal);
HRESULT [proput] HomeStreet([in] BSTR Val);

Remarks

This property is also available as the urn:schemas:contacts:homestreet field.


Initials Property

Contains the initials of the person contact.

[Visual Basic, VBScript]
Property Initials as String
[C++]
HRESULT get_Inititals(BSTR* pVal);
HRESULT put_LastName(BSTR Val);
[IDL]
HRESULT [propget] Initials([out,retval] BSTR* pVal);
HRESULT [proput] Initials([in] BSTR Val);

Remarks

In CDO, initials are calculated using the first capitalized letters for the first, middle, last name of the contact. Each initial is separated by a period. The Initials field has a maximum of six characters.

Note In Active Directory, the initials field represents the capitalized first letter of the middle name followed by a period. When a new user is created in Active Directory, the Initials field can be set to a string with a maximum of four characters.

This property is also available as the urn:schemas:contacts:initials field.

Example

In CDO: "D.E.S."

In Active Directory: "E."

© 2000-2001 Microsoft Corporation. All rights reserved.


LastName Property

Contains the last name of the person contact.

[Visual Basic, VBScript]
Property LastName as String
[C++]
HRESULT get_LastName(BSTR* pVal);
HRESULT put_LastName(BSTR Val);
[IDL]
HRESULT [propget] LastName([out,retval] BSTR* pVal);
HRESULT [proput] LastName([in] BSTR Val);

Remarks

This property is also available as the urn:schemas:contacts:sn field.


MailingAddress Property

Contains the postal mailing address of the person contact.

[Visual Basic, VBScript]
Property MailingAddress as String
Read-only
[C++]
HRESULT get_MailingAddress(BSTR* pVal);
[IDL]
HRESULT [propget] MailingAddress([out,retval] BSTR* pVal);

Remarks

This property is also available as the urn:schemas:contacts:mailingpostaladdress field.

This property is constructed from other name, city, state, country/region, and postal code properties. The MailingAddressID property identifies the source of those properties.


MailingAddressID Property

Identifies which address is the mailing address of the person contact.

[Visual Basic, VBScript]
Property MailingAddressID as String
[C++]
HRESULT get_MailingAddressID(BSTR* pVal);
HRESULT put_MailingAddressID(BSTR Val);
[IDL]
HRESULT [propget] MailingAddressID([out,retval] BSTR* pVal);
HRESULT [proput] MailingAddressID([in] BSTR Val);

Remarks

This property is also available as the urn:schemas:contacts:mailingaddressid field.

This property identifies from which other properties the MailingAddress property is constructed.

The values for this property are defined by the CdoMailingAddressIDValues enumeration.


MiddleName Property

Contains the middle name of the person contact.

[Visual Basic, VBScript]
Property MiddleName as String
[C++]
HRESULT get_MiddleName(BSTR* pVal);
HRESULT put_MiddleName(BSTR Val);
[IDL]
HRESULT [propget] MiddleName([out,retval] BSTR* pVal);
HRESULT [proput] MiddleName([in] BSTR Val);

Remarks

This property is also available as the urn:schemas:contacts:middlename field.


MobilePhone Property

Contains the mobile telephone number of the person contact.

[Visual Basic, VBScript]
Property MobilePhone as String
[C++]
HRESULT get_MobilePhone(BSTR* pVal);
HRESULT put_MobilePhone(BSTR Val);
[IDL]
HRESULT [propget] MobilePhone([out,retval] BSTR* pVal);
HRESULT [proput] MobilePhone([in] BSTR Val);

Remarks

This property is also available as the urn:schemas:contacts:mobile field.


NamePrefix Property

Contains the title to precede the name of the person contact.

[Visual Basic, VBScript]
Property NamePrefix as String
[C++]
HRESULT get_NamePrefix(BSTR* pVal);
HRESULT put_NamePrefix(BSTR Val);
[IDL]
HRESULT [propget] NamePrefix([out,retval] BSTR* pVal);
HRESULT [proput] NamePrefix([in] BSTR Val);

Remarks

This property is also available as the urn:schemas:contacts:personaltitle field.


NameSuffix Property

Contains the generation qualifier. Contains the title to follow the name of the person contact.

[Visual Basic, VBScript]
Property NameSuffix as String
[C++]
HRESULT get_NameSuffix(BSTR* pVal);
HRESULT put_NameSuffix(BSTR Val);
[IDL]
HRESULT [propget] NameSuffix([out,retval] BSTR* pVal);
HRESULT [proput] NameSuffix([in] BSTR Val);

Remarks

This property is also available as the urn:schemas:contacts:namesuffix field.

Example

“Esquire”

© 2000-2001 Microsoft Corporation. All rights reserved.


Title Property

The work title or job position of the contact.

[Visual Basic, VBScript]
Property Title as String
[C++]
HRESULT get_Title(BSTR* pVal);
HRESULT put_Title(BSTR Val);
[IDL]
HRESULT [propget] Title([out,retval] BSTR* pVal);
HRESULT [proput] Title([in] BSTR Val);

Remarks

This property is also available as the urn:schemas:contacts:title field.


WorkCity Property

Contains the work city of the person contact.

[Visual Basic, VBScript]
Property WorkCity as String
[C++]
HRESULT get_WorkCity(BSTR* pVal);
HRESULT put_WorkCity(BSTR Val);
[IDL]
HRESULT [propget] WorkCity([out,retval] BSTR* pVal);
HRESULT [proput] WorkCity([in] BSTR Val);

Remarks

This property is also available as the urn:schemas:contacts:l (locality) field.


WorkCountry Property

Contains the work country/region of the person contact.

[Visual Basic, VBScript]
Property WorkCountry as String
[C++]
HRESULT get_WorkCountry(BSTR* pVal);
HRESULT put_WorkCountry(BSTR Val);
[IDL]
HRESULT [propget] WorkCountry([out,retval] BSTR* pVal);
HRESULT [proput] WorkCountry([in] BSTR Val);

Remarks

This property is also available as the urn:schemas:contacts:co field.

Important

If you specify a value for this property, you must also specify a value for the work country/region code property, urn:schemas:contacts:c, in the schema.


WorkFax Property

Contains the work fax number of the person contact.

[Visual Basic, VBScript]
Property WorkFax as String
[C++]
HRESULT get_WorkFax(BSTR* pVal);
HRESULT put_WorkFax(BSTR Val);
[IDL]
HRESULT [propget] WorkFax([out,retval] BSTR* pVal);
HRESULT [proput] WorkFax([in] BSTR Val);

Remarks

This property is also available as the urn:schemas:contacts:facsimiletelephonenumber field.


WorkPager Property

Contains the work pager number of the person contact.

[Visual Basic, VBScript]
Property WorkPager as String
[C++]
HRESULT get_WorkPager(BSTR* pVal);
HRESULT put_WorkPager(BSTR Val);
[IDL]
HRESULT [propget] WorkPager([out,retval] BSTR* pVal);
HRESULT [proput] WorkPager([in] BSTR Val);

Remarks

This property is also available as the urn:schemas:contacts:pager field.


WorkPhone Property

Contains the work telephone number of the person contact.

[Visual Basic, VBScript]
Property WorkPhone as String
[C++]
HRESULT get_WorkPhone(BSTR* pVal);
HRESULT put_WorkPhone(BSTR Val);
[IDL]
HRESULT [propget] WorkPhone([out,retval] BSTR* pVal);
HRESULT [proput] WorkPhone([in] BSTR Val);

Remarks

This property is also available as the urn:schemas:contacts:telephonenumber field.


WorkPostalAddress Property

Contains the work postal address street number of the person contact.

[Visual Basic, VBScript]
Property WorkPostalAddress as String
Read-only
[C++]
HRESULT get_WorkPostalAddress(BSTR* pVal);
[IDL]
HRESULT [propget] WorkPostalAddress([out,retval] BSTR* pVal);

Remarks

This property contains the full address of the contact, as defined by their country/region code.


WorkPostalCode Property

Contains the work postal code (zip code for US addresses) of the person contact.

[Visual Basic, VBScript]
Property WorkPostalCode as String
[C++]
HRESULT get_WorkPostalCode(BSTR* pVal);
HRESULT put_WorkPostalCode(BSTR Val);
[IDL]
HRESULT [propget] WorkPostalCode([out,retval] BSTR* pVal);
HRESULT [proput] WorkPostalCode([in] BSTR Val);

Remarks

This property is also available as the urn:schemas:contacts:postalcode field.


WorkPostOfficeBox Property

Contains the work post office box number of the person contact.

[Visual Basic, VBScript]
Property WorkPostOfficeBox as String
[C++]
HRESULT get_WorkPostOfficeBox(BSTR* pVal);
HRESULT put_WorkPostOfficeBox(BSTR Val);
[IDL]
HRESULT [propget] WorkPostOfficeBox([out,retval] BSTR* pVal);
HRESULT [proput] WorkPostOfficeBox([in] BSTR Val);

Remarks

This property is also available as the urn:schemas:contacts:postofficebox field.


WorkState Property

Contains the work state of the person contact.

[Visual Basic, VBScript]
Property WorkState as String
[C++]
HRESULT get_WorkState(BSTR* pVal);
HRESULT put_WorkState(BSTR Val);
[IDL]
HRESULT [propget] WorkState([out,retval] BSTR* pVal);
HRESULT [proput] WorkState([in] BSTR Val);

Remarks

This property is also available as the urn:schemas:contacts:st field.


WorkStreet Property

Contains the work street of the person contact.

[Visual Basic, VBScript]
Property WorkStreet as String
[C++]
HRESULT get_WorkStreet(BSTR* pVal);
HRESULT put_WorkWorkStreet(BSTR Val);
[IDL]
HRESULT [propget] WorkStreet([out,retval] BSTR* pVal);
HRESULT [proput] WorkStreet([in] BSTR Val);

Remarks

This property is also available as the urn:schemas:contacts:street field.


GetInterface Method

Returns the specified dual interface on the object.

[Visual Basic,VBScript]
Function GetInterface(ByVal Interface as String) as Object
[C++]
HRESULT GetInterface( BSTR Interface, IDispatch** ppUnknown);
[IDL]
HRESULT GetInterface([in] BSTR Interface, [out,retval] IDispatch** ppUnknown);
Interface
The name of interface to obtain. The list of possible interfaces to return depends upon the COM class that provides the implementation.
ppUnknown [C++,IDL]
If the method succeeds, then on return, the address passed holds a reference to the requested interface.

Remarks

The GetInterface method is primarily intended as a generic interface navigation aid to scripting languages that do not support such navigation directly. Most COM classes that provide implementations of the IMessage interface expose additional dual interfaces that are accessible by scripting languages only through properties on the interface, such as BodyPart and DataSource, or through using the GetInterface method. When properties do not exist on the interface to return these interfaces, the GetInterface method must be used.

The list of valid interface names to pass to GetInterface is dependent upon a specific implementation. As a general rule, the name of the desired interface should match the physical name of the interface as it appears in the type library or idl file. Check the appropriate COM class for a list of exposed dual interfaces. If the object does not support the requested interface, an exception is raised with the HRESULT value of E_INVALIDARG.

Example

[VBScript]
Dim iPrs
Set iPrs = CreateObject("CDO.Person")
Dim iDsrc
Set iDsrc = iPrs.GetInterface("IDataSource")


GetvCardStream Method

Returns an ADO Stream object containing vCard stream information about the contact.

[Visual Basic,VBScript]
Function GetDecodedContentStream( ) as ADODB.Stream
[C++]
HRESULT GetDecodedContentStream( _Stream** Stream);
[IDL]
HRESULT GetDecodedContentStream([out,retval] _Stream** Stream);
pVal[C++,IDL]
If the method succeeds, then on return, the address passed holds a reference to the _Stream interface.

Remarks

Use the GetvCardStream method to share contact information with other PIM or contact applications that can parse vCard content.

Example

[Visual Basic]
Dim oPer As New CDO.Person
Dim strm As New ADODB.Stream

'assume strURL is a valid URL to a person contact item
oPer.DataSource.Open strURL

'you can set the ADO Stream object to the returned vCard stream
Set strm = oPer.GetvCardStream

'save the stream to a file
strm.SaveToFile "d:\vcard.txt", adSaveCreateOverwrite

'Use the Stream methods off GetvCardStream directly
oPer.GetvCardStream.SaveToFile "d:\vcard.txt", _
adSaveCreateOverwrite


IProcessDefinition Interface

Defines the workflow process for a work item.

IID
CD001022-8B95-11D1-82DB-00C04FB1625D
Extends
IDispatch

Member Summary

Properties

Name | Type | Description
ActionTable | [Visual Basic,VBScript] ADODB.RecordSet [C++,IDL] _Recordset* | Contains the state-transition rules for a workflow process definition, stored as an ADO Recordset.
AuditTrailProvider | [Visual Basic,VBScript]String [C++,IDL] BSTR | Contains the ProgID of the COM class which will be used for logging.
CommonScriptURL | [Visual Basic,VBScript]String [C++,IDL] BSTR | Contains a URL to the item containing the shared script functions referenced in the Condition and Action scripts.
DataSource (Read-Only) | IDataSource [C++,IDL] IDataSource* | Returns the IDataSource interface on the object.
DesignTool | [Visual Basic,VBScript] String [C++,IDL] BSTR | Contains a string describing the workflow design tool (if any) used to create this Process Definition.
Fields (Read-Only) | [Visual Basic,VBScript] ADODB.Fields [C++,IDL] Fields* | The property collection for the object.
Mode | [Visual Basic,VBScript] CdoWfMode [C++,IDL] CdoWfMode | Sets the type of security checking performed by the workflow engine.

Remarks

The ProcessDefinition object is stored as an item in a public folder. All properties are accessible from Microsoft® Visual Basic® and VBScript. You can use IDataSource.Save, IDataSource.SaveTo, and IDataSource.Open with IProcessDefinition to get and set properties and to save a ProcessDefinition item. However, you cannot save the ProcessDefinition object on a folder item. Calling SaveTo with the flag adCreateCollection or saving to a folder URL causes an error and will not create a folder.

See Also

Developing Advanced Workflow Applications

ProcessDefinition CoClass

© 2000-2001 Microsoft Corporation. All rights reserved.


ActionTable Property

Contains the state-transition rules for a workflow process definition, stored as an ADO Recordset. This is the central part of a workflow application.

[Visual Basic,VBScript]
Public Property ActionTable as ADODB.Recordset
[C++]
HRESULT get_ActionTable(_Recordset** ppVal);
HRESULT put_ActionTable(_Recordset* pVal);
[IDL]
HRESULT [propget] ActionTable([out,retval] _Redordset** ppVal);
HRESULT [propput] ActionTable([in] _Redordset* pVal);

Remarks

This property corresponds directly to the Web Storage System property http://schemas.microsoft.com/cdo/workflow/actiontable. Applications can also use ADO, OLEDB, or WebDAV to update this property directly. The ActionTable is persisted in Extensible Markup Language (XML) format. The workflow engine cannot read the ActionTable if it is not in this format.

When you save the ProcessDefinition, it validates the ActionTable to prevent the use of a poorly formed table.

The Action Table Recordset requires the following fourteen schema:

  1. "ID", String, Some identifier for this row (optional).
  2. "Caption", String, A display name for this step (optional).
  3. "State", String, The current state of the ProcessInstance.
  4. "NewState", String, The new state of the ProcessInstance, upon successful completion of this step.
  5. "EventType", String, The type of event this step represents. CDOWFEventType enum lists possible values.
  6. "Condition", String, A script expression, common script call, or COM object ProgID whose result is Boolean. If you write the ProcessDefinition without the help of the ProcessDefinition object, the workflow engine will evaluate empty conditions as false. If you use the ProcessDefinition object, it will validate the action table and require a condition. An empty condition causes an error. If the workflow engine does not find a row in the ActionTable with a matching CdoWfEventType and a 'TRUE' condition, it returns a failure code CDOWF_NO_CONDS_MATCHED.
  7. "EvaluationOrder",....String, The position of a row in the order in which conditions will be evaluated given multiple matching rows in a call to advance. If this column of the action table contains no values, then no order is guaranteed. Action tables may have a mixture of blank and numeric entries, but only if they are not mixed for a given current state and event type.
  8. "Action", String, A script expression, common script call, or COM object ProgID that executes if action table row matches the process instance and condition is true.
  9. "ExpiryInterval", String, The duration (in minutes) that the item should remain in the new state before triggering an OnExpiry event. This is only used with the OnEnter event type.
  10. "RowACL", String, Required field reserved for future use. It must be empty.
  11. "TransitionACL", String, You can define an ACL for the transition here that will override the default ACL which is the folder role. Valid roles include "Role1", "Role2", ... , "Role16".
  12. "DesignToolFields", String, Reserved for use by design tools such as Microsoft Workflow Designer for Exchange 2000 Server (optional).
  13. "CompensatingAction", String, A script expression, common script call, or COM object ProgID to run if the workflow transaction gets aborted.
  14. "Flags", String, Bitwise OR of cdowfTransitionFlags that indicate which columns in the action table will contain COM objects and which will contain script. Use zero (0x00) if this row contains only script conditions and actions.

The workflow engine performs a number of consistency checks as it processes a transition. The following list summarizes the checks and the error types returned by the workflow engine.

Consistency Check | Error Message
The actiontable is empty: | CDOWF_EMPTY_ACTIONTABLE
A column is missing, the data type isn't a string, or the workflow engine has any other trouble reading a row: | CDOWF_E_BAD_ACTIONTABLE
The event type is empty: | CDOWF_E_EMPTY_EVENTTYPE
The event type is not valid: | CDOWF_E_INVALID_EVENTTYPE
The State column has something in it and shouldn't have (for OnCreate and OnEnter): | CDOWF_E_NONEMPTY_CURSTATE
The State column is empty and shouldn't be: | CDOWF_E_EMPTY_CURSTATE
The NewState column has something in it and shouldn't have: | CDOWF_E_NONEMPTY_NEWSTATE
The NewState column is empty and shouldn't be: | CDOWF_E_EMPTY_NEWSTATE
A transition acl is used in an onexpiry event (OnExpiry doesn't really have a "current user", so transition acls don't make sense in this case): | CDOWF_E_TRANSITIONACL_NO_USE_ONEXPIRY
TransitionFlags is empty or not valid: | CDOWF_E_ROW_INVALID_FLAGS
EvaluationOrder has a duplicate order entry, the entry is not a number, or the sequence is not logical. | CDOWF_E_DUPLICATE_ORDER CDOWF_E_ROW_DUPLICATE_ORDER CDOWF_E_ROW_INVALID_SEQUENCENUMBER CDOWF_E_ROW_INVALID_SEQUENCING CDOWF_INVALID_EVALUATION_ORDER

Example

The following code uses Microsoft® ActiveX® Data Objects 2.5 to create a new recordset with the appropriate fields for an action table.

[Visual Basic]
   Dim Rs As ADODB.Recordset
   Set Rs = New ADODB.Recordset

   With Rs.Fields
    .Append "ID", adBSTR
    .Append "Caption", adBSTR
    .Append "State", adBSTR
    .Append "NewState", adBSTR
    .Append "EventType", adBSTR
    .Append "Condition", adBSTR
    .Append "EvaluationOrder", adBSTR
    .Append "Action", adBSTR
    .Append "ExpiryInterval", adBSTR
    .Append "RowACL", adBSTR
    .Append "TransitionACL", adBSTR
    .Append "DesignToolFields", adBSTR
    .Append "CompensatingAction", adBSTR
    .Append "Flags", adBSTR
   End With

   Dim varColumnNames As Variant

   varColumnNames = Array(Rs.Fields.Item(0).Name, _
                         Rs.Fields.Item(1).Name, _
                         Rs.Fields.Item(2).Name, _
                         Rs.Fields.Item(3).Name, _
                         Rs.Fields.Item(4).Name, _
                         Rs.Fields.Item(5).Name, _
                         Rs.Fields.Item(6).Name, _
                         Rs.Fields.Item(7).Name, _
                         Rs.Fields.Item(8).Name, _
                         Rs.Fields.Item(9).Name, _
                         Rs.Fields.Item(10).Name, _
                         Rs.Fields.Item(11).Name, _
                         Rs.Fields.Item(12).Name, _
                         Rs.Fields.Item(13).Name)

The following code creates a new Recordset object; creates the fields in the recordset; opens the Recordset; adds new records to the recordset representing the rows in the action table; saves the recordset; and closes it.

[Visual Basic]
   Rs.Open
   If Err.Number <> 0 Then
      Debug.Print "Failed to open ActionTable Recordset" & Err.Description
   End If

   With Rs
    .AddNew varColumnNames, Array("1", "OnCreate", "", "Submitted", "OnCreate", "true", "", "sendmail(""new ProcessInstance"")", "", "", "", "", "", "0")
    .AddNew varColumnNames, Array("2", "OnEnter", "", "Submitted", "OnEnter", "true", "", "sendmail(""entered submitted state"")", "", "", "", "", "", "0")
    .AddNew varColumnNames, Array("3", "OnExpiry", "Submitted", "Submitted", "OnExpiry", "true", "", "sendmail(""submitted state expired"")", "", "", "", "", "", "0")
    .AddNew varColumnNames, Array("4", "OnDelete", "Submitted", "", "OnDelete", "true", "", "sendmail(""deleted ProcessInstance"")", "", "", "", "", "", "0")
   End With

See Also

IProcessDefinition Interface

Defining the ActionTable

© 2000-2001 Microsoft Corporation. All rights reserved.


AuditTrailProvider Property

Contains the ProgID of the COM class which will be used for logging.

[Visual Basic,VBScript]
Property AuditTrailProvider As String
[C++]
HRESULT get_AuditTrailProvider(BSTR* pVal);
HRESULT put_AuditTrailProvider(BSTR Val);
[IDL]
HRESULT [propget] AuditTrailProvider([out,retval] BSTR* pVal);
HRESULT [propput] AuditTrailProvider([in] BSTR Val);

Remarks

This property corresponds directly to the Web Storage System property http://schemas.microsoft.com/cdo/workflow/audittrailprovider. Applications can also use ADO, OLEDB, or WebDAV to update this property directly.

  1. The AuditTrailProvider must support IAuditTrail interface. Cdowf.dll includes AuditTrailEventLog which writes to the Microsoft® Windows® 2000 event log.

Example

The following example defines a ProcessDefinition variable, creates the object, and uses the object to set the AuditTrailProvider property.

[Visual Basic]
Dim strProgID As String
Dim iPd As CDOWF.ProcessDefinition
Set iPd = New CDOWF.ProcessDefinition

'strProgID may be the ProgID of a provider that you wrote
'or the sample provider included with Workflow for
'Microsoft Exchange Platinum.
With iPd
   .AuditTrailProvider = strProgID
End With

See Also

Bind Method

AddEntry Method

AuditTrail Property

© 2000-2001 Microsoft Corporation. All rights reserved.


CommonScriptURL Property

Contains a URL to the item containing the shared script functions referenced in the Condition and Action scripts.

[Visual Basic,VBScript]
Public Property CommonScriptURL as String
[C++]
HRESULT get_CommonScriptURL(BSTR* pVal);
HRESULT put_CommonScriptURL(BSTR Val);
[IDL]
HRESULT [propget] CommonScriptURL([out,retval] BSTR* pVal);
HRESULT [propput] CommonScriptURL([in] BSTR Val);

Remarks

This property corresponds directly to the Web Storage System property http://schemas.microsoft.com/cdo/workflow/commonscripturl. Applications can also use ADO, OLEDB, or WebDAV to update this property directly.

You can think of this as the location of your "include" file. You should save your common script functions in a text file at the location specified by this URL. Save the CommonScript file to this URL before setting this property to avoid problems with different versions.

You can use either an absolute or a relative URL for this property. If you use a relative URL, it must refer to an item in the same folder or a subfolder of the event sink registration item. Use the string "self" to indicate that the commonscript text is stored as the default file stream on the ProcessDefinition item.

Example

[Visual Basic]
  Dim DomainName As String
  Dim FolderName As String
  Dim CommonScriptItem As String

  ' set your own values to these variables:
  DomainName = "microsoft.com"
  FolderName = "Workflow1"
  CommonScriptItem = "CommonScript.txt"

  Dim strURL As String
  strURL = "file://./backofficestorage/" _
          & DomainName _
          & "/Public Folders/" _
          & FolderName & "/" _
          & CommonScriptItem

  Dim iPd As CDOWF.ProcessDefinition
  Set iPd = New CDOWF.ProcessDefinition

  iPd.CommonScriptURL = strURL

See Also

Conditions and Actions

© 2000-2001 Microsoft Corporation. All rights reserved.


DataSource Property

Returns the IDataSource interface on an object.

[Visual Basic,VBScript]
Public Property DataSource as IDataSource
read-only
[C++]
HRESULT get_DataSource(IDataSource** ppVal);
[IDL]
HRESULT [propget] DataSource([out,retval] IDataSource** ppVal);

Remarks

This property returns the IDataSource interface on the object.

With VBScript, you cannot omit certain optional parameters when accessing IDataSource methods, such as SaveTo and Open. When the second argument is a _Connection interface, it must be explicitly set to 'Nothing'. If you get a run-time 'Type Mismatch' error when using SaveTo or Open, try setting the second argument to 'Nothing'.

Example

The following example shows the use of the IDataSource interface on the ProcessDefinition object to create a new ProcessDefinition item by binding to a new URL, creating the ActionTable, setting some properties on the item, and saving the item.

[Visual Basic]
   Dim iPD As New CDOWF.ProcessDefinition
   Dim conn As New ADODB.Connection

   sDomainURL = "file://./backofficestorage/" _
                & Environ("USERDNSDOMAIN") & _
                "/Public Folders/"
   sFolderURL = sDomainURL & sFolderName
   sProcDefURL = sFolderURL & "/" & sProcDef

   conn.Provider = "ExOleDb.DataSource"
   conn.Open sFolderURL
   conn.BeginTrans

   With iPD
    .ActionTable = Rs
   'Rs is an open ADODB.Recordset built at run time

    .AuditTrailProvider = "CdoWf.AuditTrailEventLog"
    .CommonScriptURL = sCommonScriptURL
    .Mode = cdowfPrivilegedMode
    .Fields("DAV:ishidden") = True
   End With

   iPD.DataSource.SaveTo sProcDefURL, _
                         conn, _
                         adModeReadWrite, _
                         adCreateOverwrite Or adCreateNonCollection

   conn.CommitTrans


DesignTool Property

Contains a string describing the workflow design tool (if any) used to create this ProcessDefinition.

[Visual Basic,VBScript]
Public Property DesignTool as String
[C++]
HRESULT get_DesignTool(BSTR* pVal);
HRESULT put_DesignTool(BSTR Val);
[IDL]
HRESULT [propget] DesignTool([out,retval] BSTR* pVal);
HRESULT [propput] DesignTool([in] BSTR Val);

Remarks

This property corresponds directly to the Web Storage System property http://schemas.microsoft.com/cdo/workflow/designtool. Applications can also use ADO, OLEDB, or WebDAV to update this property directly.

This property is for informational purposes only and does not affect the execution of a workflow. If you are writing a workflow design tool, use this field to store information specific to your design tool. For example, use this property in your tool to determine which workflow designs are compatible with your tool.

Example

Note This example uses a file URL with the Exchange OLE DB (ExOLEDB) provider. The ExOLEDB provider also supports the HTTP URL scheme.

[Visual Basic]
     Dim pd As New CDOWF.ProcessDefinition
   Dim iDsrc As IDataSource
   Set iDsrc = pd.DataSource

   Dim PdItemURL As String
   PdItemURL = "file://./backofficestorage/" & _
               Environ("USERDNSDOMAIN") & _
               "/Public Folders/workflow/test1/design1.wfd"
   iDsrc.Open PdItemURL

   Dim ToolName As String
   ToolName = "Microsoft Workflow Designer for Exchange 2000 Server 1.0.27"
   pd.DesignTool = ToolName

   iDsrc.Save

See Also

Modeling Business Processes

© 2000-2001 Microsoft Corporation. All rights reserved.


Fields Property

The property collection for the object.

[Visual Basic,VBScript]
Property Fields As Fields
[C++]
HRESULT Fields([out, retval] Fields** varFields);
[IDL]
HRESULT Fields([out, retval] Fields** varFields);

Remarks

In general, you have three methods for assigning properties with Microsoft® ActiveX® Data Objects (ADO) and Collaboration Data Objects (CDO).

  • Use the fields collection on a record object (ADO)
  • Use the fields collection on a CDO object (CDO)
  • Use the CDO property name with a CDO object (CDO)

CDO Workflow does not support the second method for workflow schema properties. You can only use the second method for your own custom properties.

If you are familiar with ADO, you are used to setting properties on a record using the fields collection. For example:

   Dim Rec As ADODB.Record
   'Bind record object to the item on which you want to set properties
   'Use the workflow schema name to set the property on the item
   Rec.fields("http://schemas.microsoft.com/cdo/workflow/commonscripturl") = "yourURL"

CDO Workflow supports the previous assignment type for most workflow properties. However, it does not support assigning workflow schema properties by using the Fields collection with a CDO Workflow object. The following is not supported, for example:

   Dim pd As CDOWF.ProcessDefinition
   'Get datasource interface on ProcessDefinition and open item
   'This is not supported
   pd.fields("http://schemas.microsoft.com/cdo/workflow/commonscripturl") = "yourURL"

If you have the workflow object, as in the previous code, simply use the workflow property. For example:

pd.CommonScriptURL = "yourURL"

You can use the Workflow object with the Fields collection in an assignment only for your custom properties. The following assignment is acceptable, for example:

   Dim pd As CDOWF.ProcessDefinition
   'Get datasource interface on ProcessDefinition and open item
   pd.fields("YourNameSpace://workflow/yourcustomproperty") = "yourURL"

The previous discussion applies to all the workflow objects that support the Fields collection.

Note When you use the ADO Fields.Update method, field values are updated only in memory. You must call IDataSource.Save to save the changes to the Web Storage System. To get the IDataSource interface, use the GetInterface method on the CDO object.


Mode Property

Sets the type of security checking performed by the workflow engine.

[Visual Basic,VBScript]
Public Property Mode as CdoWfMode
[C++]
HRESULT get_Mode(CdoWfMode* pVal);
HRESULT put_Mode(CdoWfMode Val);
[IDL]
HRESULT [propget] Mode([out,retval] CdoWfMode* pVal);
HRESULT [propput] Mode([in] CdoWfMode Val);

Remarks

This property corresponds directly to the property in the Web Storage System http://schemas.microsoft.com/cdo/workflow/mode. Applications can also use ADO, OLEDB, or WebDAV to update this property directly.

The Microsoft® Exchange 2000 Server workflow engine will run in one of two modes:

  • Restricted
  • Privileged

In restricted mode, all executable workflow code is limited to a small number of “safe” actions. The script engine is in a constrained process such that no other COM objects can be co-created. Code executes under a security context with little or no permission (anonymous).

In privileged mode, the script engine is able to co-create any registered COM objects. Creating COM objects lets you integrate with other systems such as SQL databases and other business applications that provide COM components. You can also use LDAP and Active Directory in privileged mode. COM objects may also be used, in place of script, for workflow actions. The code executes under the same Windows® 2000 security context as the workflow engine itself—typically the Workflow System Account defined by the server administrator.

Workflow Event Sink (CdoWfEvt) checks for which mode a workflow runs in at run-time. CdoWfEvt component has a COM+ Application Role PrivilegedWorkflowAuthors attached to it. Only workflows authored by (last saved by) members of this role are allowed to run in unlimited mode. Second, the workflow author must also explicitly request that the workflow execute in unlimited mode, by setting a flag (Mode) on the ProcessDefinition object.

Example

The following example defines variables for a ProcessDefinition object and a IDataSource interface; creates the objects in memory; opens the ProcDefURL object with read/write access; sets the Mode property to 'Privileged' mode; and saves the change back to the ProcDefURL row in the Web Storage System.

[Visual Basic]
Dim iPd As CDOWF.ProcessDefinition
Dim iDsrc As CDO.IDataSource

Set iPd = New CDOWF.ProcessDefinition
Set iDsrc = iPd

'ProcDefURL must be a valid URL to a ProcessDefinition item
iDsrc.Open ProcDefURL, _
           Nothing, _
           adModeReadWrite, _
           adFailIfNotExists

With iPd
   .Mode = cdowfPrivilegedMode
End With

iDsrc.Save

See Also

Restricted Mode

Privileged Mode

© 2000-2001 Microsoft Corporation. All rights reserved.


IProcessInstance Interface

Represents a document in a workflow folder.

IID
CD001023-8B95-11D1-82DB-00C04FB1625D
Extends
IDispatch

Member Summary

Properties

Name | Type | Description
AuditTrail | IAuditTrail [C++,IDL] IAuditTrail* | Contains a pointer to the current IAuditTrail interface object that is bound to a process instance.
CurrentState | [Visual Basic,VBScript] String [C++,IDL] BSTR | Contains any string of characters that represents the state of the ProcessInstance item set by the workflow engine.
DataSource (Read-Only) | IDataSource [C++,IDL] IDataSource* | Returns the IDataSource interface on the object.
Fields (Read-Only) | [Visual Basic,VBScript] ADODB.Fields [C++,IDL] Fields* | The property collection for the object.
ProcessDefinition (Read-only) | [Visual Basic,VBScript] IProcessDefinition [C++,IDL] IProcessDefinition* | Returns a pointer to the ProcessDefinition for a ProcessInstance.
ProcessDefinitionURL | Basic,VBScript] String [C++,IDL] BSTR* | An absolute URL to a row containing an existing ProcessDefinition item. Allows a new ProcessInstance to specify which ProcessDefinition it should use for its workflow.
TrackingTable (Read-Only) | Basic,VBScript] Recordset [C++,IDL] _Recordset* | Contains records of all messages correlated with ProcessInstance in an e-mail–based workflow.

Methods

Name | Description
Advance | Evaluates the action table for this process instance and executes appropriate actions. This method is called internally by the CDO Workflow Event Sink, and does not need to be used by most applications.
DisableSuccessEntries | Enables the user to configure entry types for the AuditTrail.
EnableDebug | Enables script just in time debugging.
OnAbort | Runs compensating action scripts and cleans up when a workflow transaction gets aborted.

Remarks

A new item in a workflow folder becomes a ProcessInstance, except in the following instances:

  • The new item was mailed and can be correlated to an existing ProcessInstance in the folder.
  • The new item is a hidden item.

You do not have to do anything to create the ProcessInstance object. The event sink takes care of this whenever an item is saved or mailed to the folder. Normally, you will not use the ProcessInstance object directly unless you want to implement your own event sink.


AuditTrail Property

Contains a pointer to the current object bound to the process instance that implements the IAuditTrail interface.

(Read-only)

[Visual Basic,VBScript]
Property AuditTrail As AuditTrailEventLog
    read-only
[C++]
HRESULT AuditTrail(IAuditTrail** varAuditTrail);
[IDL]
HRESULT AuditTrail([out, retval] IAuditTrail** varAuditTrail);

Remarks

(Read-only)

Example

The following code shows how to get the read-only AuditTrail property of ProcessInstance and use it to add an entry to an application log.

[C++]
/*
   assume that a ProcessInstance is created and
   an audit trail object is bound to the ProcessInstance
*/
  CComPtr<IAuditTrail> pAuditTrail;
  if(SUCCEEDED(hr = pProcessInstance->get_AuditTrail(&pAuditTrail)))
  {
     CComBSTR bsErrDesc(L"Your error description");
     hr = pAuditTrail->AddEntry(bsErrDesc,
                                E_FAIL,
                                cdowfATECustom,
                                CComVariant());
  }

See Also

AuditTrailProvider Property

© 2000-2001 Microsoft Corporation. All rights reserved.


CurrentState Property

Contains any string of characters that represents the state of the ProcessInstance item set by the workflow engine. (Read-only)

[Visual Basic,VBScript]
Public Property CurrentState as String
read-only
[C++]
HRESULT get_CurrentState(BSTR* pVal);
[IDL]
HRESULT [propget] CurrentState([out,retval] BSTR* pVal);

Remarks

This string property contains the name of a logical state for this process instance, such as Expired, Submitted, or Approved. The workflow engine compares this property to rows in an action table to determine what action to take.

This property corresponds directly to the Web Storage System property http://schemas.microsoft.com/cdo/workflow/currentstate. Applications can also use ADO, OLEDB, or WebDAV to update this property directly.


DataSource Property

Returns the IDataSource interface on the object.

[Visual Basic,VBScript]
Public Property DataSource as IDataSource
read-only
[C++]
HRESULT get_DataSource(IDataSource** pVal);
[IDL]
HRESULT [propget] DataSource([out,retval] IDataSource** pVal);

Remarks

This property returns the IDataSource interface on the object.

With Microsoft® Visual Basic® Scripting Edition (VBScript), you cannot omit certain optional parameters when accessing IDataSource methods, such as SaveTo and Open. When a second argument is an _Connection interface, it must be explicitly set to 'Nothing'. If you get a run-time 'Type Mismatch' error when using SaveTo or Open, set the second argument to 'Nothing'.


Fields Property

The property collection for the object.

[Visual Basic,VBScript]
Property Fields As Fields
[C++]
HRESULT Fields([out, retval] Fields** varFields);
[IDL]
HRESULT Fields([out, retval] Fields** varFields);

Remarks

In general, you have three methods for assigning properties with Microsoft® ActiveX® Data Objects (ADO) and Collaboration Data Objects (CDO).

  • Use the fields collection on a record object (ADO)
  • Use the fields collection on a CDO object (CDO)
  • Use the CDO property name with a CDO object (CDO)

CDO Workflow does not support the second method for workflow schema properties. You can only use the second method for your own custom properties.

If you are familiar with ADO, you are used to setting properties on a record using the fields collection. For example:

   Dim Rec As ADODB.Record
   'Bind record object to the item on which you want to set properties
   'Use the workflow schema name to set the property on the item
   Rec.fields("http://schemas.microsoft.com/cdo/workflow/commonscripturl") = "yourURL"

CDO Workflow supports the previous assignment type for most workflow properties. However, it does not support assigning workflow schema properties by using the Fields collection with a CDO Workflow object. The following is not supported, for example:

   Dim pd As CDOWF.ProcessDefinition
   'Get datasource interface on ProcessDefinition and open item
   'This is not supported
   pd.fields("http://schemas.microsoft.com/cdo/workflow/commonscripturl") = "yourURL"

If you have the workflow object, as in the previous code, simply use the workflow property. For example:

pd.CommonScriptURL = "yourURL"

You can use the Workflow object with the Fields collection in an assignment only for your custom properties. The following assignment is acceptable, for example:

   Dim pd As CDOWF.ProcessDefinition
   'Get datasource interface on ProcessDefinition and open item
   pd.fields("YourNameSpace://workflow/yourcustomproperty") = "yourURL"

The previous discussion applies to all the workflow objects that support the Fields collection.

Note When you use the ADO Fields.Update method, field values are updated only in memory. You must call IDataSource.Save to save the changes to the Web Storage System. To get the IDataSource interface, use the GetInterface method on the CDO object.

See Also

IItem Fields

© 2000-2001 Microsoft Corporation. All rights reserved.


ProcessDefinition Property

Returns a pointer to ProcessDefinition for ProcessInstance.

(Read-only)

[Visual Basic,VBScript]
Property ProcessDefinition As ProcessDefinition
[C++]
HRESULT ProcessDefinition(IProcessDefinition** varProcessDefinition);
[IDL]
HRESULT ProcessDefinition([out, retval] IProcessDefinition** varProcessDefinition);

Remarks

(Read-only)

The workflow event sink checks for a ProcessDefinitionURL on a new ProcessInstance. If the item has no ProcessDefinitionURL, the sink checks the ProcessDefinition property for a value. If it finds none, it uses the default folder ProcessDefinition to start a new workflow. If the sink finds a ProcessDefinition on a ProcessInstance, the sink checks the CdoWfAdhocFlows flag of the OnSyncSave registration item in the workflow folder. Set the CdoWfAdhocFlows flag to OnlyAdhocFlows or PermitAdhocFlows in the OnSyncSave registration item for this property to work.

See Also

CdoWfAdhocFlows Enum

Registering Workflow Event Sink

© 2000-2001 Microsoft Corporation. All rights reserved.


ProcessDefinitionURL Property

Contains an absolute URL to a row containing an existing ProcessDefinition. Allows a new ProcessInstance to specify which ProcessDefinition it should use for its workflow.

[Visual Basic,VBScript]
Public Property ProcessDefinitionURL as String
[C++]
HRESULT get_ProcessDefinitionURL (BSTR** pVal);
HRESULT put_ProcessDefinitionURL (BSTR* Val);
[IDL]
HRESULT [propget] ProcessDefinitionURL([out,retval] BSTR** pVal);
HRESULT [propput] ProcessDefinitionURL ([in] BSTR* Val);

Remarks

You can only use absolute URLs in the ProcessDefinitionURL property. Setting this property automatically creates a ProcessDefinition object and loads the ProcessDefinition from the specified URL into the ProcessDefinition property of the ProcessInstance object. You can use the ProcessDefinition property of the ProcessInstance to reference the newly created ProcessDefinition object.

This property corresponds directly to the property in the Web Storage System http://schemas.microsoft.com/cdo/workflow/processdefinition. Applications can also use ADO, OLEDB, or WebDAV to update this property directly. When updating the Web Storage System property directly with ADO, OLEDB, or WebDAV, you can use relative URL's. In this case, no ProcessDefinition object is created or loaded in the ProcessInstance.

See Also

Default and Ad hoc Process Definitions

ProcessDefinition Property

© 2000-2001 Microsoft Corporation. All rights reserved.


TrackingTable Property

Contains records of all messages correlated with ProcessInstance in an e-mail–based workflow.

[Visual Basic,VBScript]
Public Property TrackingTable as Recordset
[C++]
HRESULT get_TrackingTable (_Recordset* pVal);
HRESULT put_TrackingTable (_Recordset Val);
[IDL]
HRESULT [propget] TrackingTable ([out,retval] _Recordset* pVal);
HRESULT [propput] TrackingTable ([in] _Recordset Val);

Remarks

The workflow engine uses the TrackingTable to store information regarding e-mails correlated with ProcessInstance. If the engine matches a row in the ActionTable with an OnReceive event, it makes an entry in the TrackingTable for the ReceivedMessage.

The tracking table provides you with ten fields that you can use to store additional properties you may wish to track. These are the custom0 through custom9 fields.

Records in the TrackingTable have the following fields:

Field Name | Type | Maximum Size | May be NULL
email | WCHAR | 512 characters | No
trackingid | WCHAR | 512 characters | Yes
date | WCHAR | 512 characters | No
state | WCHAR | 512 characters | No
flags | WCHAR | 512 characters | No
response | WCHAR | 512 characters | Yes
custom0 - custom9 | WCHAR | 512 characters | Yes

TrackingTable Field Semantics
email
This contains the address in the 'To' field of outgoing forms or messages.
trackingid
This is a GUID created by the workflow engine when you use SendWorkflowMessage(). The engine uses this GUID to correlate all subsequent messages associated with the ProcessInstance.
date
For outgoing messages, this is the 'sent' time. For incoming messages, this is the 'received' time.
state
The workflow engine puts the state of ProcessInstance here when you use SendWorkflowMessage(). It puts the ProcessInstance state in this field for all correlated responses as well.
flags
This can be 'STRICT', 'ADD', or 'INCOMING'. When you use SendWorkflowMessage(2), the engine puts 'STRICT' in this field.
response
The workflow engine automatically copies the value of the form field "http://schemas.microsoft.com/cdo/workflow/response" into this column without you having to write any code.
custom0 - custom9
These are ten fields that you can use to store data from your form. You need to write the script code to copy the data to the TrackingTable.

This property corresponds directly to the Web Storage System property http://schemas.microsoft.com/cdo/workflow/trackingtablexml. Applications can also use ADO, OLEDB, or WebDAV to update this property directly.


Advance Method

Evaluates the action table for this process instance and executes appropriate actions. This method is called internally by the CDO Workflow Event Sink, and does not need to be used by most applications.

Visual Basic]
Function Advance(eEventType As CdoWfEventType, _
                 varReceived, _
                 varUserID,
                 [pConnection As Connection])
                 As Boolean
[C++]
HRESULT Advance(
                CdoWfEventType eEventType,
                VARIANT varReceived,
                VARIANT varUserID,
                _Connection* pConnection,
                VARIANT_BOOL* pbEnd);

[IDL]
HRESULT Advance(
                [in] CdoWfEventType eEventType,
                [in] VARIANT varReceived,
                [in] VARIANT varUserID,
                [in, optional, defaultvalue(0)] _Connection* pConnection,
                  [out, retval] VARIANT_BOOL* pbEnd);

Remarks

If you are using the workflow designer, you do not need to use this method. The built-in workflow components take care of calling this method based on your selections.

This method with its supporting implementation is called the workflow engine. Normally, you will not need to use this method, as the workflow event sink invokes it for you in response to an event in your folder. When the event sink calls, the engine looks for a row in your ActionTable that matches the CdoWfEventType passed to it and contains a condition field that evaluates to 'TRUE'. If it does not find a match with a 'TRUE' condition, it treats it as an error and returns the code CDOWF_NO_CONDS_MATCHED. If you want to allow editing of a workflow document without changing state, enter a transition in your ActionTable with a 'TRUE' condition and no action.

You must bind to the ProcessInstance before every call to Advance, and you must save the ProcessInstance after every call to Advance. This is the only supported behavior for Advance. The following example illustrates the correct sequence.

Bind to ProcessInstance item
Call Advance
Save ProcessInstance item

Bind to ProcessInstance item
Call Advance
Save ProcessInstance item
eEventType
The event type can be one of the events in the CdoWfEventType_cdo_CdoWfEventType_enum enumeration. You only use this method if you are writing your own workflow event sink.
varReceived
The received message that initiated the workflow transition. This parameter should be empty for all events other than OnReceive.
varUserID
The security ID of the user currently modifying the message. This can be a security identifier (SID) of type VT_ARRAY | VT_UI1 and value is SAFEARRAY of bytes corresponding to the SID, or it can be a string of the form domain\username of type VT_BSTR and value is BSTR.
pConnection
Advance includes an input parameter of type pointer to ActiveX Data Objects Connection. The workflow engine uses this parameter to supply the same session as the ProcessInstance to SendWorkflowMessage(). This ensures that e-mail sent in conjunction with the ProcessInstance transaction is committed or aborted along with ProcessInstance. If you are calling Advance from VBScript, this parameter has to be a valid Connection or Nothing. If you do not supply a valid Connection or set this to Nothing, a Type Mismatch error is generated.
pbEnd
If the return value is true, it means the ProcessInstance entered a state marked as the end state. You indicate an end state by using cdoWfEndState(8) constant in the Flags field of the ActionTable.

Example

[Visual Basic]
Dim eventType As CdoWfEventType
'Assume OnChange action for this example
eventType = cdowfOnChange

Dim varReceived As Variant
'If this is a correlated e-mail response
'Get the item that initiated the event
'Call it Row for this example
varReceived = Row

Dim varUserID As Variant
'Get the security ID of the user that initiated the event
'Call it Sid for this example
varUserID = Sid

Dim pConnection As New ADODB.Connection
'FolderURL is the URL of the folder where you run your workflow
pConnection.Open folderURL
pConnection.BeginTrans

Dim oPI As New CDOWF.ProcessInstance
'URL is the ProcessInstance URL
oPI.DataSource.Open URL, pConnection, adModeReadWrite

'You need this connection to the PrivateURL of the WorkflowAccount
'only if you are using sendworkflowmessage in the action
Dim pInboxConnection As New ADODB.Connection
Dim PrivateURL As String
pInboxConnection.Open PrivateURL

Dim bEnd As Boolean
bEnd = oPI.Advance(eventType, _
                   varReceived, _
                   varUserID, _
                   pInboxConnection)

'If Advance fails then call OnAbort
If Err.Number <> 0 Then
    oPI.OnAbort varReceived, varUserID
    'Undo changes caused by advance
    pConnection.RollbackTrans
Else 'commit transaction
    oPI.DataSource.Save
    pConnection.CommitTrans
End If

See Also

OnAbort Method

© 2000-2001 Microsoft Corporation. All rights reserved.


DisableSuccessEntries Method

Allows the user to configure entry types for AuditTrail.

[Visual Basic,VBScript]
Sub DisableSuccessEntries(bDisable As Boolean)
[C++]
HRESULT DisableSuccessEntries(VARIANT_BOOL bDisable);
[IDL]
HRESULT DisableSuccessEntries([in] VARIANT_BOOL bDisable);

Remarks

If you are using the workflow designer, you do not need to use this method. The built-in workflow components take care of calling this method based on your selections.

You can configure the Audit Trail provider to not log success entries to the audit trail using the "http://schemas.microsoft.com/cdo/workflow/disablesuccessentries" property with the "OnSyncSave;OnSyncDelete" event registration item. Setting this property to "TRUE" disables success entries.

If you are an advanced developer, you can accomplish the same thing using the DisableSuccessEntries() method by passing in a VARIANT_TRUE parameter. This assumes you are writing your own event sink and have already created a ProcessInstance object.

Example

This example shows the event registration for "OnSyncSave;OnSyncDelete". You set the "http://schemas.microsoft.com/cdo/workflow/disablesuccessentries" Web Storage System property in this registration event record.

[Visual Basic]
  EventRuleItem = "OnSyncSave_OnSyncDelete_Rule"

'assumes sFolderURL is a string representing
'your application folder where you want to
'register the events
  sEvtRegURL = sFolderURL & EventRuleItem

'assumes sProcDefURL is a string representing
'the process definition item for this folder
  ProcessDefinitionURL = sProcDefURL

  Rec.Open sEvtRegURL, , adModeReadWrite, _
                       adCreateNonCollection Or adCreateOverwrite, _
                       adDelayFetchFields
  If Err.Number <> 0 Then
     Debug.Print "Failed to open event registration record." & Err.Description
  End If

  With Rec
    Set Flds = .fields
    Flds("DAV:contentclass") = "urn:content-class:storeeventreg"
    Flds("http://schemas.microsoft.com/exchange/events/EventMethod") = "OnSyncSave;OnSyncDelete"
    Flds("http://schemas.microsoft.com/exchange/events/SinkClass") = "CdoWfEvt.EventSink.1"
    Flds("http://schemas.microsoft.com/exchange/events/Criteria") = "WHERE $DAV:ishidden$ = FALSE"
    Flds("http://schemas.microsoft.com/cdo/workflow/defaultprocdefinition") = ProcessDefinitionURL
    Flds("http://schemas.microsoft.com/cdo/workflow/adhocflows") = 0
    Flds("http://schemas.microsoft.com/cdo/workflow/enabledebug") = True
    Flds("http://schemas.microsoft.com/cdo/workflow/disablesuccessentries") = False
    Flds.Update
    .Close
  End With
© 2000-2001 Microsoft Corporation. All rights reserved.


EnableDebug Method

Enables script Just-In-Time (JIT) debugging.

[Visual Basic,VBScript]
Sub EnableDebug(bDebug As Boolean)
[C++]
HRESULT EnableDebug(VARIANT_BOOL bDebug);
[IDL]
HRESULT EnableDebug([in] VARIANT_BOOL bDebug);

Remarks

If you are using the workflow designer, you do not need to use this method. The built-in workflow components take care of calling this method based on your selections.

This property corresponds directly to the Web Storage System property http://schemas.microsoft.com/cdo/workflow/enabledebug. Applications can also use ADO, OLEDB, or WebDAV to update this property directly.

If you are an advanced developer, writing your own event sink, you can call this method to enable the Just-In-Time (JIT) script debugging capability. You configure this capability by setting the "http://schemas.microsoft.com/cdo/workflow/enabledebug" property of the OnSyncSave;OnSyncDelete event registration item for your workflow folder. If you don't set this property explicitly, the event sink sets it to 'FALSE'.

Note JIT script debugging requires certain server environment settings in order to work properly.

You use JIT debugging for run-time errors. However, JIT debugging does not catch syntax errors. The workflow engine logs syntax errors in the AuditTrail.

Example

This example shows the event registration for "OnSyncSave;OnSyncDelete". You set the "http://schemas.microsoft.com/cdo/workflow/enabledebug" Web Storage System property in this registration event record.

[VBScript]
  EventRuleItem = "OnSyncSave_OnSyncDelete_Rule"

'assumes sFolderURL is a string representing
'your application folder where you want to
'register the events
  sEvtRegURL = sFolderURL & EventRuleItem

'assumes sProcDefURL is a string representing
'the process definition item for this folder
  ProcessDefinitionURL = sProcDefURL

  Rec.Open sEvtRegURL, , adModeReadWrite, _
                       adCreateNonCollection Or adCreateOverwrite, _
                       adDelayFetchFields
  If Err.Number <> 0 Then
     Debug.Print "Failed to open event registration record." & Err.Description
  End If

  With Rec
    Set Flds = .fields
    Flds("DAV:contentclass") = "urn:content-class:storeeventreg"
    Flds("http://schemas.microsoft.com/exchange/events/EventMethod") = "OnSyncSave;OnSyncDelete"
    Flds("http://schemas.microsoft.com/exchange/events/SinkClass") = "CdoWfEvt.EventSink.1"
    Flds("http://schemas.microsoft.com/exchange/events/Criteria") = "WHERE $DAV:ishidden$ = FALSE"
    Flds("http://schemas.microsoft.com/cdo/workflow/defaultprocdefinition") = ProcessDefinitionURL
    Flds("http://schemas.microsoft.com/cdo/workflow/adhocflows") = 0
    Flds("http://schemas.microsoft.com/cdo/workflow/enabledebug") = True
    Flds("http://schemas.microsoft.com/cdo/workflow/disablesuccessentries") = False
    Flds.Update
    .Close
  End With
© 2000-2001 Microsoft Corporation. All rights reserved.


OnAbort Method

Runs compensating action scripts and cleans up when a workflow transaction is aborted.

Visual Basic]
Sub OnAbort(varReceived, varUserID)
[C++]
HRESULT OnAbort(
                VARIANT varReceived,
                VARIANT varUserID);
[IDL]
HRESULT OnAbort(
                [in] VARIANT varReceived,
                [in] VARIANT varUserID);

Remarks

The OnAbort method causes the CompensatingAction script to run. When calling OnAbort, make sure you use the same varReceived and varUserID parameters that you used in the associated call to Advance. If the OnAbort parameters do not match the corresponding parameters in the Advance call, OnAbort behavior is undefined. Undefined behavior means the wrong CompensatingAction or no CompensatingAction may be called.

CompensatingAction script is only run for corresponding actions that have already run. For example in a typical OnChange/OnExit/OnEnter sequence, if the OnChange transition fails, the OnExit and OnChange actions get rolled back. The OnEnter action would not have run, so its corresponding CompensatingAction does not run.

If you are using the workflow designer, you do not need to use this method. The built-in workflow components take care of calling this method based on your selections.

The event sink supplies the parameters to this method. Use this method only if you are writing your own workflow event sink.

The following pseudocode illustrates the only supported use of the OnAbort method.

Open a connection
Begin Transaction
Call Advance
if failed then
   Call OnAbort
   Rollback transaction
else
   Save
   Commit Transaction
end if

See Also

Advance Method

© 2000-2001 Microsoft Corporation. All rights reserved.


IPublicStoreDB Interface

This interface provides access to Microsoft® Exchange 2000 Server public stores.

IID
25150F44-5734-11D2-A593-00C04F990D8A
Extends
IDispatch

Member Summary

Properties

Name | Type | Description
DataSource (Read-Only) | IDataSource2 [C++,IDL] IDataSource2* | Returns the IDataSource2 interface on the object.
DaysBeforeItemExpiration | [Visual Basic,VBScript] Long [C++,IDL] Long | The age limit for folders in this store, in days.
DaysBeforeGarbageCollection | [Visual Basic,VBScript] Long [C++,IDL] Long | The days before deleted items will be permanently deleted from the store.
DBPath | [Visual Basic,VBScript] String [C++,IDL]BSTR | The path for the MDB.
Enabled | [Visual Basic,VBScript] Boolean [C++,IDL] VARIANT_BOOL | A Boolean indicating whether this store should be mounted at start-up
Fields (Read-Only) | [Visual Basic] ADODB.Fields [C++,IDL] Fields* | The object's Fields collection.
FolderTree | [Visual Basic,VBScript] String [C++,IDL]BSTR | The folder tree in this MDB.
GarbageCollectionOnlyAfterBackup | [Visual Basic,VBScript] Boolean [C++,IDL] VARIANT_BOOL | A Boolean indicating that items can be permanently deleted from the store only after they have been backed up.
HardLimit | [Visual Basic,VBScript] Long [C++,IDL] Long | The quota limit at which messages will be rejected.
ItemSizeLimit | [Visual Basic,VBScript] Long [C++,IDL] Long | The maximum size of a message, in kilobytes.
Name | [Visual Basic,VBScript] String [C++,IDL]BSTR | The name of the public store.
SLVPath (Read-Only) | [Visual Basic,VBScript] String [C++,IDL]BSTR | The path for stream files.
Status (Read-Only) | [Visual Basic,VBScript] CDOEXMStoreDBStatus [C++,IDL]CDOEXMStoreDBStatus | The current status for the MDB.
StoreQuota | [Visual Basic,VBScript] Long [C++,IDL] Long | The maximum size allowed for the store (in kilobytes).

Methods

Name | Description
Dismount | Dismount the MDB.
GetInterface | Returns the specified dual interface on the object.
Mount | Mount the MDB.
MoveDataFiles | Move and change the paths for data files.


DataSource Property

Returns the IDataSource2 interface on this object.

[Visual Basic]
Property DataSource as IDataSource2
read-only
[C++]
HRESULT get_DataSource(IDataSource2** pVal);
[IDL]
HRESULT [propget] DataSource([out,retval] IDataSource2** pVal);

Remarks

You can use the DataSource property to obtain the IDataSource2 interface on this object. This is equivalent to using QueryInterface in C++ or Set in Visual Basic, or using the GetInterface method.


DaysBeforeItemExpiration Property

The age limit for folders in this store, in days.

[Visual Basic,VBScript]
Property DaysBeforeItemExpiration as Long
[C++]
HRESULT get_DaysBeforeItemExpiration(long* pVal);
HRESULT put_DaysBeforeItemExpiration(long Val);
[IDL]
HRESULT [propget] DaysBeforeItemExpiration([out,retval] long* pVal);
HRESULT [propput] DaysBeforeItemExpiration([in] long Val);

Remarks

If this value is 0 then there is no expiration.


DaysBeforeGarbageCollection Property

Gets or sets the days before deleted items (in the garbage) are permanently deleted from the server.

[Visual Basic,VBScript]
Property DaysBeforeGarbageCollection as Long
[C++]
HRESULT get_DaysBeforeGarbageCollection(long* pVal);
HRESULT put_DaysBeforeGarbageCollection(long Val);
[IDL]
HRESULT [propget] DaysBeforeGarbageCollection([out,retval] long* pVal);
HRESULT [propput] DaysBeforeGarbageCollection([in] long Val);

Remarks

The default value for this property is -1 (no collection).

See DaysBeforeItemExpiration for related information.


DBPath Property

The path for the MDB.

[Visual Basic,VBScript]
Property DBPath as String
read-only
[C++]
HRESULT get_DBPath(BSTR* pVal);
[IDL]
HRESULT [propget] DBPath([out,retval] BSTR* pVal);


Enabled Property

Indicates whether this store should be mounted at start-up.

[Visual Basic,VBScript]
Property Enabled as Boolean
[C++]
HRESULT get_Enabled(VARIANT_BOOL* pVal);
HRESULT put_Enabled(VARIANT_BOOL pVal);
[IDL]
HRESULT [propget] Enabled([out,retval] VARIANT_BOOL* pVal);
HRESULT [propput] Enabled([in] VARIANT_BOOL pVal);

Remarks

When set to true, the store will be mounted at start-up.


Fields Property

The Fields collection for the object.

[Visual Basic]
Property Fields as ADODB.Fields
read-only
[C++]
HRESULT get_Fields(Fields** pVal);
[IDL]
HRESULT [propget] Fields([out,retval] Fields** pVal);

Remarks

The Fields property obtains a collection of ADO Field objects, each of which contains a field relating to the PublicStoreDB object.

Note When you use the ADO Fields.Update method, field values are updated only in memory. You must call IDataSource.Save to save the changes to the Web Storage System. To get the IDataSource interface, use the GetInterface method on the CDO object.


FolderTree Property

The folder tree in this MDB

[Visual Basic,VBScript]
Property FolderTree as String
[C++]
HRESULT get_FolderTree(BSTR* pVal);
HRESULT put_FolderTree(BSTR pVal);
[IDL]
HRESULT [propget] FolderTree([out,retval] BSTR* pVal);
HRESULT [propput] FolderTree([in] BSTR Val);

Remarks

See Web Storage System Configuration for related information.


GarbageCollectionOnlyAfterBackup Property

When enabled, this property prevents permanent deletion of items from the public store unless they have been backed up.

[Visual Basic,VBScript]
Property GarbageCollectionOnlyAfterBackup as Boolean
[C++]
HRESULT get_GarbageCollectionOnlyAfterBackup(VARIANT_BOOL* pVal);
HRESULT put_GarbageCollectionOnlyAfterBackup(VARIANT_BOOL pVal);
[IDL]
HRESULT [propget] GarbageCollectionOnlyAfterBackup([out,retval] VARIANT_BOOL* pVal);
HRESULT [propput] GarbageCollectionOnlyAfterBackup([in] VARIANT_BOOL pVal);

Remarks

When set to true, items in the store that have not been backed up cannot be permanently deleted.


HardLimit Property

The quota limit at which messages will be rejected.

[Visual Basic,VBScript]
Property HardLimit as Long
[C++]
HRESULT get_HardLimit(long* pVal);
HRESULT put_HardLimit(long Val);
[IDL]
HRESULT [propget] HardLimit([out,retval] long* pVal);
HRESULT [propput] HardLimit([in] long Val);

Remarks

If this value is 0 then there is no limit.


ItemSizeLimit Property

The maximum size of a message, in kilobytes.

[Visual Basic,VBScript]
Property ItemSizeLimit as Long
[C++]
HRESULT get_ItemSizeLimit(long* pVal);
HRESULT put_ItemSizeLimit(long Val);
[IDL]
HRESULT [propget] ItemSizeLimit([out,retval] long* pVal);
HRESULT [propput] ItemSizeLimit([in] long Val);

Remarks

If this value is 0 then there is no limit.


Name Property

Returns or sets the name of the public store.

[Visual Basic,VBScript]
Property Name as String
[C++]
HRESULT get_Name(BSTR* pVal);
HRESULT put_Name(BSTR pVal);
[IDL]
HRESULT [propget] Name([out,retval] BSTR* pVal);
HRESULT [propput] Name([in] BSTR Val);


Status Property

Gets the status for this MDB.

[Visual Basic]
Property Status as CDOEXMStoreDBStatus
(read-only)
[C++]
HRESULT get_Status(CDOEXMStoreDBStatus* pVal);
[IDL]
HRESULT [propget] Status([out,retval] CDOEXMStoreDBStatus* pVal);

Remarks

The CDOEXMStoreDBStatus enumeration is provided for this property. The status can indicate if the store is on-line, off-line, mounting or dismounting.


StoreQuota Property

The maximum size allowed for the MDB (in kilobytes).

[Visual Basic,VBScript]
Property StoreQuota as Long
[C++]
HRESULT get_StoreQuota(long* pVal);
HRESULT put_StoreQuota(long Val);
[IDL]
HRESULT [propget] StoreQuota([out,retval] long* pVal);
HRESULT [propput] StoreQuota([in] long Val);

Remarks

If this value is 0 then there is no limit to the MDB size.


Dismount Method

Dismount this MDB.

[Visual Basic,VBScript]
Function Dismount(Optional Timeout as Long)
[C++]
HRESULT Dismount(long Timeout);
[IDL]
HRESULT Dismount([in,optional] long Timeout);
Timeout
The time in seconds to attempt dismounting.

Remarks

The default value for Timeout is -1 (no time out).

The MDB can be dismounted even if the MDB is enabled. However, if the Server is restarted, the MDB will automatically be mounted again.


GetInterface Method

Returns the specified dual interface on the object.

[Visual Basic]
Function GetInterface(ByVal Interface as String) as Object
[C++]
HRESULT GetInterface(BSTR Interface, IDispatch** pVal);
[IDL]
HRESULT GetInterface([in] BSTR Interface, [out,retval] IDispatch** pVal);
Interface
The name of interface to obtain.

Remarks

The GetInterface method is primarily intended as a generic interface navigation aid for scripting languages that do not support such navigation directly. Most COM classes that provide implementations of the IMessage interface expose additional dual interfaces that are accessible by scripting languages only through properties on the interface, such as BodyPart and DataSource, or through the GetInterface method. When properties do not exist on the interface to return these interfaces, the GetInterface method must be used.

The list of valid interface names to pass to GetInterface is dependent upon a specific implementation. As a general rule, the name of the desired interface should match the physical name of the interface as it appears in the type library or IDL (.idl) file. Check the appropriate COM class for a list of exposed dual interfaces.

Example

The following example in VBScript demonstrates using GetInterface to return other interfaces on a PublicStoreDB object.

[VBScript]
Dim istoredb as IPublicStoreDB
Dim idsrc as IDataSource2

'Create an instance and get IPublicStoreDB (IDispatch) back
Set istoredb = CreateObject("CDOEXM.PublicStoreDB")

'Get IDataSource2 on the PublicStoreDB Object
Set idsrc = istoredb.GetInterface("IDataSource2")
[JScript]
var istoredb = new ActiveXObject("CDOEXM.PublicStoreDB");
var iDsrc = istoredb.GetInterface("IDataSource2");


Mount Method

Mount this MDB.

[Visual Basic,VBScript]
Function Mount(Optional Timeout as Long)
[C++]
HRESULT Mount(long Timeout);
[IDL]
HRESULT Mount([in,optional] long Timeout);
Timeout
The time in seconds to attempt dismounting.

Remarks

The default value for Timeout is -1 (no time out).

You will need to mount the MDB if it has been dismounted, newly created, or re-enabled. To mount the MDB the server must be running and the MDB must be enabled.


MoveDataFiles Method

Relocates files to different paths and sets the path locations for new files.

[Visual Basic,VBScript]
Function MoveDataFiles(DBPath As String,
                       SLVPath As String,
                       Optional Flags as Long)
[C++]
HRESULT MoveDataFiles(BSTR DBPath,
                      BSTR SLVPath,
                      long Flags);
[IDL]
HRESULT MoveDataFiles([in] BSTR DBPath,
                      [in] BSTR SLVPath,
                      [in,optional] long Flags);
DBPath
The new path for the MDB.
SLVPath
The new path for the SLV (stream) files.
Flags
Reserved for future use.

Remarks

When you move the files, the specified paths become the paths for new files.

Note You must Dismount the store before moving MDB.


IRecurrencePattern Interface

This interface provides scheduling properties for specifying recurrence pattern rules.

When you create an appointment or meeting, you can make it into a recurring appointment or meeting by creating one or more RecurrencePattern objects. When you process a recurring appointment or meeting, the RecurrencePattern objects define the recurring instances.

A RecurrencePattern object can either define a set of appointment instances, or it can define a set of exceptions to instances defined by other RecurrencePattern objects.

Note CDO supports a maximum of 10 instances in a single day. If the Frequency value is minutely or secondly, the instances are only expanded for the first day of the pattern.

IID
CD000123-8B95-11D1-82DB-00C04FB1625D
Extends
IDispatch

Member Summary

Properties

Name | Type | Description
ByPosition (Read-only) | [Visual Basic,VBScript] IIntegers [C++,IDL]] IIntegers* | Contains the relative position of an instance in a recurrence pattern.
DaysOfMonth (Read-only) | [Visual Basic,VBScript] IIntegers [C++,IDL ]]IIntegers* | Contains the days of the month when a recurrence pattern is valid.
DaysOfWeek (Read-only) | [Visual Basic,VBScript] IIntegers [C++,IDL] IIntegers* | Contains the days of the week when a recurrence pattern is valid.
DaysOfYear (Read-only) | [Visual Basic,VBScript] IIntegers [C++,IDL] IIntegers* | Contains the days of the year when a recurrence pattern is valid.
EndType | [Visual Basic,VBScript] CdoPatternEndType [C++,IDL] CdoPatternEndType* | Specifies how a recurring pattern ends.
FirstDayOfWeek | [Visual Basic,VBScript] CdoDayOfWeek [C++,IDL] CdoDayOfWeek* | Contains the day when a week starts, such as Sunday or Monday.
Frequency | [Visual Basic,VBScript] CdoFrequency [C++,IDL] CdoFrequency* | Contains the recurring type of the pattern, such as daily or weekly.
HoursOfDay (Read-only) | [Visual Basic,VBScript] IIntegers [C++,IDL ]IIntegers* | Contains the hours of the day when a recurrence pattern is valid.
Instances | [Visual Basic,VBScript] Long [C++,IDL] long | Contains the number of instances generated by the pattern.
Interval | [Visual Basic,VBScript] Long [C++,IDL] long | Contains the interval between any two instances generated by the pattern.
MinutesOfHour (Read-only) | [Visual Basic,VBScript] IIntegers [C++,IDL] IIntegers* | Contains the minutes of the hour when a recurrence pattern is valid.
MonthsOfYear (Read-only) | [Visual Basic,VBScript] IIntegers [C++,IDL] IIntegers* | Contains the months of the year when a recurrence pattern is valid.
PatternEndDate | [Visual Basic,VBScript] Date [C++,IDL] DATE | Contains the date and time on which the recurrence pattern terminates.
SecondsOfMinute (Read-only) | [Visual Basic,VBScript] IIntegers [C++,IDL] IIntegers* | Contains the seconds of a minute when a recurrence pattern is valid.
Type (Read-only) | [Visual Basic,VBScript] String [C++,IDL] BSTR | Contains the instruction of whether to add or delete a set of appointment instances from a recurring appointment.
WeekDays (Read-only) | [Visual Basic,VBScript] IVariants [C++,IDL] IVariants* | Contains values describing the weeks, the days of the week, and when appointment instances should occur.
WeeksOfYear (Read-only) | [Visual Basic,VBScript] IIntegers [C++,IDL] IIntegers* | Contains the weeks of the year and when a recurrence pattern is valid.


ByPosition Property

The relative position of the instance in a recurrence pattern. For example, in a monthly recurrence pattern, a ByPosition value of -1 indicates the last day of the month.

[Visual Basic,VBScript]
Property ByPosition As IIntegers
Read-Only
[C++]
HRESULT get_ByPosition(IIntegers* pVal);
[IDL]
HRESULT [propget] ByPosition([out,retval] IIntegers* pVal);

Remarks

This property is stored as an integer collection using the IIntegers interface. Valid values are 1 to 366 and -1 to -366.


DaysOfMonth Property

The days of the month spanned by the recurrence pattern.

[Visual Basic,VBScript]
Property DaysOfMonth As IIntegers
Read-Only
[C++]
HRESULT get_DaysOfMonth(IIntegers* pVal);
[IDL]
HRESULT [propget] DaysOfMonth([out,retval] IIntegers* pVal);

Remarks

This property is stored as an integer collection using the IIntegers interface. Valid values are 1 to 31, identifying the spanned days of the month for the pattern.


DaysOfWeek Property

The days of the week spanned by the recurrence pattern.

[Visual Basic,VBScript]
Property DaysOfWeek As IIntegers
Read-Only
[C++]
HRESULT get_DaysOfWeek(IIntegers* pVal);
[IDL]
HRESULT [propget] DaysOfWeek([out,retval] IIntegers* pVal);

Remarks

This property is stored as an integer collection using the IIntegers interface. The integer for each day is specified by the CdoDayOfWeek enumeration value.


DaysOfYear Property

The days of the year spanned by a recurrence pattern.

[Visual Basic,VBScript]
Property DaysOfYear As IIntegers
Read-Only
[C++]
HRESULT get_DaysOfYear(IIntegers* pVal);
[IDL]
HRESULT [propget] DaysOfYear([out,retval] IIntegers* pVal);

Remarks

This property is stored as an integer collection using the IIntegers interface. The possible integer values in the collection range from 1 to 365, each denoting a particular day of the year, where 1 is January 1 and 365 is December 31.


EndType Property

Specifies how a recurring pattern ends.

[Visual Basic,VBScript]
Property EndType As CdoPatternEndType
[C++]
HRESULT get_EndType(CdoPatternEndType * pVal);
HRESULT put_EndType(CdoPatternEndType Val);
[IDL]
HRESULT [propget] EndType([out,retval] CdoPatternEndType * pVal);
HRESULT [proput] EndType([in] CdoPatternEndType Val);

Remarks

The CdoPatternEndType enumeration is used to set this property and is as follows:

Name | Value | Description
cdoNoEndDate | 0 | The pattern never ends.
cdoEndByInstances | 1 | The pattern ends after a specified number of instances.
cdoEndByDate | 2 | The pattern ends after a specified date and time.

You must first specify the number of instances for the pattern using the IRecurrencePattern.Instances property if you plan to set the EndType property to cdoEndByInstances. If you do not specify the number of instances first, CDO raises an error.

You must first specify the recurrence end date using the IRecurrencePattern.PatternEndDate property if you plan to set the EndType property to cdoEndByDate. If you do not specify this date first, CDO raises an error.


FirstDayOfWeek Property

The day when a week starts, such as Sunday or Monday.

[Visual Basic,VBScript]
Property FirstDayOfWeek As CdoDayOfWeek
[C++]
HRESULT get_FirstDayOfWeek(CdoDayOfWeek* pVal);
HRESULT put_FirstDayOfWeek(CdoDayOfWeek Val);
[IDL]
HRESULT [propget] FirstDayOfWeek([out,retval] CdoDayOfWeek* pVal);
HRESULT [proput] FirstDayOfWeek([in] CdoDayOfWeek Val);

Remarks

The CdoDayOfWeek enumeration is used to set this property and is as follows:

Name | Value | Description
cdoDayOfWeekSunday | 0 | Sunday
cdoDayOfWeekMonday | 1 | Monday
cdoDayOfWeekTuesday | 2 | Tuesday
cdoDayOfWeekWednesday | 3 | Wednesday
cdoDayOfWeekThursday | 4 | Thursday
cdoDayOfWeekFriday | 5 | Friday
cdoDayOfWeekSaturday | 6 | Saturday


Frequency Property

The frequency of the recurring appointment, such as daily or weekly.

[Visual Basic,VBScript]
Property Frequency As CdoFrequency
[C++]
HRESULT get_Frequency(CdoFrequency* pVal);
HRESULT put_Frequency(CdoFrequency Val);
[IDL]
HRESULT [propget] Frequency([out,retval] CdoFrequency* pVal);
HRESULT [proput] Frequency([in] CdoFrequency Val);

Remarks

The CdoFrequency enumeration is provided for use with this property and is as follows:

Name | Value | Description
cdoSecondly | 1 | The event happens once a second.*
cdoMinutely | 2 | The event happens once a minute.*
cdoHourly | 3 | The event happens once an hour.*
cdoDaily | 4 | The event happens once a day.
cdoWeekly | 5 | The event happens once a week.
cdoMonthly | 6 | The event happens once a month.
cdoYearly | 7 | The event happens once a year.

*Multiple instances in a single day may not be supported by your mail client.

Note CDO supports a maximum of 10 instances in a single day. If the Frequency value is minutely or secondly, the instances are only expanded for the first day of the pattern.


HoursOfDay Property

The hours of the day spanned by the recurrence pattern.

[Visual Basic,VBScript]
Property HoursOfDay as IIntegers
Read-Only
[C++]
HRESULT get_HoursOfDay(IIntegers* pVal);
[IDL]
HRESULT [propget] HoursOfDay([out,retval] IIntegers* pVal);

Remarks

This property is stored as an integer collection using the IIntegers interface. Each integer in the collection identifies an hour in the day spanned by the recurrence pattern.


Instances Property

Contains the number of instances generated by the pattern.

[Visual Basic,VBScript]
Property Instances As Long
[C++]
HRESULT get_Instances(long* pVal);
HRESULT put_Instances(long Val);
[IDL]
HRESULT [propget] Instances([out,retval] long* pVal);
HRESULT [proput] Instances([in] long Val);


Interval Property

The interval between any two recurring appointment instances generated by the pattern.

[Visual Basic,VBScript]
Property Interval As Long
[C++]
HRESULT get_Interval(long* pVal);
HRESULT put_Interval(long Val);
[IDL]
HRESULT [propget] Interval([out,retval] long* pVal);
HRESULT [proput]  Interval([in] long Val);


MinutesOfHour Property

The minutes of the hour spanned by the recurrence pattern.

[Visual Basic,VBScript]
Property MinutesOfHour As IIntegers
Read-Only
[C++]
HRESULT get_MinutesOfHour(IIntegers* pVal);
[IDL]
HRESULT [propget] MinutesOfHour([out,retval] IIntegers* pVal);

Remarks

This property is stored as an integer collection using the IIntegers interface. Each integer in the collection identifies a minute in the hour spanned by the recurrence pattern. Possible values range from 1 to 60.


MonthsOfYear Property

The months of the year spanned by the recurrence pattern.

[Visual Basic,VBScript]
Property MonthsOfYear As IIntegers
Read-Only
[C++]
HRESULT get_MonthsOfYear(IIntegers* pVal);
[IDL]
HRESULT [propget] MonthsOfYear([out,retval] IIntegers* pVal);

Remarks

This property is stored as an integer collection using the IIntegers interface. Each integer in the collection identifies a month in the year spanned by the recurrence pattern. Possible values range from 1 to 12, where 1 denotes January and 12 denotes December.


PatternEndDate Property

The date and time that the recurrence pattern terminates.

[Visual Basic,VBScript]
Property PatternEndDate As Date
[C++]
HRESULT get_PatternEndDate(DATE* pVal);
HRESULT put_PatternEndDate(DATE Val);
[IDL]
HRESULT [propget] PatternEndDate([out,retval] DATE* pVal);
HRESULT [proput] PatternEndDate([in] DATE Val);

Remarks

Recurrence patterns in CDO can have more than one instance a day. To include all possible instances on a given date, specify the PatternEndDate value as 11:59:59 PM on that date.


SecondsOfMinute Property

The seconds of a minute spanned by the recurrence pattern.

[Visual Basic,VBScript]
Property SecondsOfMinute As IIntegers
Read-Only
[C++]
HRESULT get_SecondsOfMinute(IIntegers* pVal);
[IDL]
HRESULT [propget] SecondsOfMinute([out,retval] IIntegers* pVal);

Remarks

This property is stored as an integer collection using the IIntegers interface. Each integer in the collection identifies a second in the minute spanned by the recurrence pattern. Possible values range from 1 to 60, where 1 denotes the first second of the minute, and 60 denotes the last.


Type Property

Denotes whether the appointment instances defined by the recurrence pattern are to be added or deleted from the overall recurring appointment.

[Visual Basic,VBScript]
Property Type As String
read-only
[C++]
HRESULT get_Type(BSTR* pVal);
[IDL]
HRESULT [propget] Type([out,retval] BSTR* pVal);

Remarks

If the value of this property is "ADD," the appointment instances defined by this RecurrencePattern object are added to the recurring appointment. If the value of this property is "DELETE," the appointment instances defined by this RecurrencePattern object are deleted from the recurring appointment.

The value of this property is set from the Type parameter of the IRecurrencePatterns::Add method when adding a recurrence pattern to the recurring appointment. The value "ADD" corresponds to the iCalendar RRULE field. The value "DELETE" corresponds to the iCalendar EXRULE field.


WeekDays Property

Contains values describing the weeks and the days of the week when appointment instances should occur.

[Visual Basic,VBScript]
Property WeekDays As IVariants
Read-Only
[C++]
HRESULT get_WeekDays(IVariants* pVal);
[IDL]
HRESULT [propget] WeekDays([out,retval] IVariants* pVal);


WeeksOfYear Property

The weeks of the year spanned by the recurrence pattern.

[Visual Basic,VBScript]
Property WeeksOfYear As IIntegers
Read-Only
[C++]
HRESULT get_WeeksOfYear(IIntegers* pVal);
[IDL]
HRESULT [propget] WeeksOfYear([out,retval] IIntegers* pVal);

Remarks

This property is stored as an integer collection using the IIntegers interface. Each integer in the collection identifies a week in the year spanned by the recurrence pattern. Possible values range from 1 to 53 or -53 to -1. A week is defined as a seven-day period starting on the day of the week as specified by the FirstDayOfWeek property of the IRecurrencePattern interface. For yearly recurrence pattern rules, the first week of the calendar year is the first week that contains at least four days in that calendar year.

Note Assuming Monday is specified as the first day of the week, week 53 can only occur if January 1 is a Thursday, or if it is a leap year and January 1 is a Wednesday.


IRecurrencePatterns Interface

The IRecurrencePatterns interface defines properties and methods that enable access to a collection of RecurrencePattern objects.

When you create an appointment, you can make the appointment into a recurring appointment by using the IRecurrencePatterns interface to add one or more RecurrencePattern objects. When you process a recurring appointment, you need to use the IRecurrencePatterns interface to get access to the RecurrencePattern objects that define recurring instances of the appointment.

IID
CD00012C-8B95-11D1-82DB-00C04FB1625D
Extends
IDispatch

Member Summary

Properties

Name | Type | Description
Count (Read-only) | [Visual Basic,VBScript] Long [C++,IDL] long | Returns the number of RecurrencePattern objects in the collection.
Item (Read-only) | [Visual Basic,VBScript] IRecurrencePattern [C++,IDL] IRecurrencePattern* | Returns a reference to the object at a given index in the collection.
_NewEnum (Read-only) | [Visual Basic,VBScript] (Used in For Each In) [C++,IDL] IUnknown* | Returns an IEnumVariant interface on an enumeration object. (This property is hidden from Microsoft® Visual Basic® and is used in For Each in constructs.)

Methods

Name | Description
Add | Adds a RecurrencePattern object to the collection.
Delete | Removes the specified RecurrencePattern object from the collection.

Remarks

The indexing of the collection always ranges from 1 to the value returned by the Count property.


Count Property

Returns the number of RecurrencePattern objects in the collection.

[Visual Basic,VBScript]
Property Count As Long
read-only
[C++]
HRESULT get_Count(long* pVal);
[IDL]
HRESULT [propget] Count([out,retval] long* pVal);


Item Property

Returns the RecurrencePattern object specified by the index.

[Visual Basic,VBScript]
Property Item(ByVal Index As Long) As IRecurrencePattern
read-only
[C++]
HRESULT get_Item(long* Index, IRecurrencePattern** pVal);
[IDL]
HRESULT [propget] Item([in] long Index, [out,retval] IRecurrencePattern** pVal);

Remarks

The indexing of the collection always ranges from 1 to the value returned by the Count property.

Item is the default member on the interface.


_NewEnum Property

Returns an IEnumVariant interface on an enumeration object for the collection. This property is hidden from Microsoft® Visual Basic and Microsoft® Visual Basic® Scripting Edition (VBScript).

[Visual Basic,VBScript]
Used automatically in For Each In constructs
[C++]
HRESULT get__NewEnum(IUnknown** pVal);
[IDL]
HRESULT [propget] _NewEnum([out,retval] IUnknown** pVal);

Remarks

This property is "hidden" within Visual Basic and VBScript. It is a standard property used to support enumerating collections, such as the

For Each in

construct in Visual Basic.

Example

[Visual Basic]
Dim iRp as IRecurrencePattern
Dim iRps as IRecurrencePatterns
...
For Each iRp in iRps   ' _NewEnum used internally here
...
Next iRp
© 2000-2001 Microsoft Corporation. All rights reserved.


Add Method

Adds a new RecurrencePattern object to the collection.

To add the appointment instances defined by this RecurrencePattern object to a recurring appointment, specify the Type parameter as ADD. To delete the appointment instances defined by this RecurrencePattern object from a recurring appointment, specify the Type parameter as DELETE.

[Visual Basic,VBScript]
Sub Add(Type As String) As IRecurrencePattern
[C++]
HRESULT Add(BSTR Type, IRecurrencePattern** pVal);
[IDL]
HRESULT Add(
[in] BSTR Type,
[out, retval] IRecurrencePattern** pVal);
);
Type

"ADD" or "DELETE"

Remarks

The Type value "ADD" corresponds to the iCalendar RRULE. The Type value "DELETE" corresponds to the iCalendar EXRULE.


Delete Method

Removes the specified RecurrencePattern object from the collection.

[Visual Basic,VBScript]
Sub Delete(Index as Long)
[C++]
HRESULT Delete(long* Index);
[IDL]
HRESULT Delete([in] LONG Index );
Index
The ordinal index of the RecurrencePattern object within the collection to remove.

Remarks

The indexing of the collection always ranges from 1 to the value returned by the Count property.


ISessionProps Interface

Provides a mechanism to cache your custom properties across script invocations within a single advance call.

IID
CD001106-8B95-11D1-82DB-00C04FB1625D
Extends
IDispatch

Member Summary

Methods

Name | Description
Get | Returns a variant type value of the property on the process instance row identified by the input string.
Put | Writes a string property name and variant type value to the row representing a process instance.

See Also

IWorkflowSession Properties Property

© 2000-2001 Microsoft Corporation. All rights reserved.


Get Method

Returns a variant type value of the property on the process instance row identified by the input string.

[Visual Basic,VBScript]
Function Get(bsName As String) as Variant
[C++]
HRESULT Get(BSTR bsName,
            VARIANT* pvarValue);
[IDL]
HRESULT Get([in] BSTR bsName,
            [out, retval] VARIANT* pvarValue);

Remarks

Use this method to retrieve a property that you have previously stored using the Put method. You can retrieve stored properties within the same state transition including condition and action scripts. Stored custom properties are not available to a compensating action.

Example

[VBScript]
'In the Condition or Action script:
GetCustomProp "MyPropName"

'In the Shared Script:
Sub GetCustomProp(propName)
   WorkflowSession.Properties.Get (propName)
End Sub

See Also

IWorkflowSession Properties Property

© 2000-2001 Microsoft Corporation. All rights reserved.


Put Method

Writes a string property name and variant type value to the row representing a process instance.

[Visual Basic,VBScript]
Sub Put(bsName As String, varValue)
[C++]
HRESULT Put(BSTR bsName,
            VARIANT varValue);
[IDL]
HRESULT Put([in] BSTR bsName,
            [in] VARIANT varValue);

Remarks

Use this property to store a property that you can retrieve later with the Get method. This property is available to subsequent function calls within one state transition. This includes the condition and action scripts but not the compensating action.

Example

[VBScript]
'In the Condition or Action script:
PutCustomProp "MyPropName", MyPropValue

'In the Shared Script
Sub PutCustomProp(propName, propValue)
   WorkflowSession.Properties.Put propName, propValue
End Sub

See Also

IWorkflowSession Properties Property

© 2000-2001 Microsoft Corporation. All rights reserved.


ISMTPOnArrival Interface

The ISMTPOnArrival interface defines the interface between event sinks written with CDO and the SMTP service OnArrival event source.

IID
CD000026-8B95-11D1-82DB-00C04FB1625D
Extends
IDispatch

Member Summary

Method

Name | Description
OnArrival | Called by the SMTP event source on bound OnArrival event sinks when a new message has arrived to the SMTP service.

Remarks

To implement an SMTP OnArrival event sink using CDO, you create and register a local COM class that provides an implementation of the CDO ISMTPOnArrival interface.

The passed CDO Message object is bound to an ADO Stream object containing the message contents within the SMTP transport. To commit any changes you make to the transport content, call IDataSource.Save. This does not affect the EnvelopeFields collection. Changes to the EnvelopeFields collection for the message are committed to the transport using the Fields.Update method for the collection.

The transport ADO Stream object is required to modify the message contents in the SMTP transport. If you want to bind the Message object to another object within your sink, using for example IDataSource.OpenObject or IDataSource.SaveToObject, make sure to first retrieve the transport Stream object reference using the Message object's IDataSource.Source property. If you do not, you will not be able to rebind the Message object to the transport Stream object and consequently you will not be able to update the message contents in the transport.

For more information on writing SMTP event sinks using CDO, see SMTP/NNTP Transport Event Sinks with CDO.

Example

[C++,IDL]

The code below is an example using the Active Template Library (ATL) to implement an SMTP OnArrival event sink.

#include "StdAfx.h"
#include "sinkproj.h"  // contains guids for this class
#include "resource.h"
#import "c:\program files\common files\system\ado\msado15.dll" raw_interfaces_only no_namespace
#import "c:\program files\common files\microsoft shared\cdo\cdoex.dll" raw_interfaces_only no_namespace
class ATL_NO_VTABLE CMyClass :
    public CComObjectRootEx<CComSingleThreadModel>,
    public CComCoClass<CMyClass,&CLSID_MyClass>,
    public IDispatchImpl<ISMTPOnArrival,&__uuidof(ISMTPOnArrival),&LIBID_MyClass>
{
public:
     CMyClass() {}
DECLARE_REGISTRY_RESOURCEID(IDR_MyClass)
DECLARE_NOT_AGGREGATABLE(CMyClass)

BEGIN_COM_MAP(CMyClass)
  COM_INTERFACE_ENTRY(ISMTPOnArrival)
  COM_INTERFACE_ENTRY(IDispatch)
END_COM_MAP()

// ISMTPOnArrival
public:
   STDMETHOD(OnArrival) (/* in */ IMessage* pMsg, /* in,out */ CdoEventStatus* pEventStatus);
private:
   // any other custom methods you wish to use

};

CMyClass::OnArrival( IMessage* pMsg, CdoEventStatus* pEventStatus)
{
   // TODO:  add sink code here
}
[Visual Basic]
' Reference to ADO 2.5 and CDO for Microsoft Exchange
Implements CDO.ISMTPOnArrival

Private Sub ISMTPOnArrival_OnArrival( ByVal Msg As IMessage, pEventStatus as CdoEventStatus )
  Msg.TextBody = Msg.TextBody & vbCrLf & "Text added by the sink."
  ' Commit the changes into the transport Stream
  Msg.DataSource.Save
End Sub
[VBScript]
<SCRIPT LANGUAGE="VBScript">
Sub ISMTPOnArrival_OnArrival( ByVal Msg, EventStatus )
  Msg.TextBody = Msg.TextBody & vbCrLf & "Text added by the sink."
  ' Commit the changes into the transport Stream
  Msg.DataSource.Save
End Sub
</SCRIPT>

See Also

SMTP/NNTP Transport Event Sinks with CDO

© 2000-2001 Microsoft Corporation. All rights reserved.


OnArrival Method

Called by the SMTP event source on bound OnArrival event sinks when a new message has arrived to the SMTP service.

[Visual Basic]
Sub OnArrival(ByVal Msg as CDO.Message, EventStatus as CdoEventStatus)
[C++]
HRESULT OnArrival(IMessage* Msg, CdoEventStatus* EventStatus);
[IDL]
HRESULT OnArrival([in] IMessage* Msg, [in,out] CdoEventStatus* EventStatus);
Msg
The IMessage interface on a Message object holding the message that arrived.
EventStatus
On return, the status of the event. The event sink signals to the source whether to continue notifying subsequent event sinks, or to stop and return. These values make up the CdoEventStatus enumeration in the type library.

Remarks

The Message object passed to the OnArrival method is in unexpanded format; the recipient addresses have not been resolved or expanded, and are thus still in the format in which the sending message transfer agent placed them in the message envelope.

For SMTP OnArrival events, the message content is read-write and can be modified by the sink. Additionally, some of the envelope fields can be modified. For more information, see SMTP/NNTP Transport Event Sinks with CDO.

The passed CDO Message object is bound to an ADO Stream object containing the message contents within the SMTP transport. To commit any changes you make to the transport content, call IDataSource.Save. This does not affect the EnvelopeFields collection. Changes to the EnvelopeFields collection for the message are committed to the transport using the Fields.Update method for the collection.

The transport ADO Stream object is required to modify the message contents in the SMTP transport. If you want to bind the Message object to another object within your sink, using for example IDataSource.OpenObject or IDataSource.SaveToObject, make sure to first retrieve the transport Stream object reference using the Message object's IDataSource.Source property. If you do not, you will not be able to rebind the Message object to the transport Stream object and consequently you will not be able to update the message contents in the transport.

The OnArrival event for the SMTP service is synchronous, meaning that the event dispatcher thread is blocked for the duration of time required for either all bound event sinks to be created (if necessary) and executed, or until a sink preemptively stops event notifications by returning the EventStatus parameter with the value cdoSkipRemainingSinks.

See Also

SMTP/NNTP Transport Event Sinks with CDO

CdoEventStatus Enum

IMessage Interface

© 2000-2001 Microsoft Corporation. All rights reserved.


IStorageGroup Interface

This interface provides access to storage groups in Microsoft® Exchange 2000 Server.

IID
25150F46-5734-11D2-A593-00C04F990D8A
Extends
IDispatch

Member Summary

Properties

Name | Type | Description
CircularLogging | [Visual Basic,VBScript] Boolean [C++,IDL] VARIANT_BOOL | A Boolean which when set, limits the size of the log file by overwriting the oldest logs once a limit has been reached.
DataSource (Read-Only) | IDataSource2 [C++,IDL] IDataSource2* | Returns the IDataSource2 interface on the object.
Fields (Read-Only) | [Visual Basic] ADODB.Fields [C++,IDL] Fields* | The object's Fields collection.
Name | [Visual Basic,VBScript] String [C++,IDL]BSTR | The name of the storage group.
LogFilePath (Read-Only) | [Visual Basic,VBScript] String [C++,IDL] BSTR | The JET_paramLogFilePath property.
SystemFilePath (Read-Only) | [Visual Basic,VBScript] String [C++,IDL]BSTR | The JET_paramSystemFilePath property.
ZeroDatabase | [Visual Basic,VBScript] Boolean [C++,IDL] VARIANT_BOOL | The JET_paramZeroDatabaseDuringBackup property.
PublicStoreDBs (Read-only) | [Visual Basic,VBScript] Variant [C++,IDL] VARIANT | A list of public store databases in the storage group.
MailboxStoreDBs (Read-only) | [Visual Basic,VBScript] Variant [C++,IDL] VARIANT | A list of mailbox store databases.

Methods

Name | Description
GetInterface | Returns the specified dual interface on the object.
MoveLogFiles | Moves log files or points to log files.
MoveSystemFiles | Moves system files or points to system files.


CircularLogging Property

A Boolean which when set, limits the size of the log file by overwriting the oldest logs once a limit has been reached.

[Visual Basic,VBScript]
Property CircularLogging as Boolean
[C++]
HRESULT get_CircularLogging(VARIANT_BOOL* pVal);
HRESULT put_CircularLogging(VARIANT_BOOL pVal);
[IDL]
HRESULT [propget] CircularLogging([out,retval] VARIANT_BOOL* pVal);
HRESULT [propput] CircularLogging([in] VARIANT_BOOL pVal);

Remarks

This prevents log files from growing indefinitely. When the log file if full, the oldest entries in the log file are replaced with the new entries that need to be logged.

Log file size is defaulted to 5120 KB. The log file size is set via the msExchESEParamLogFileSize in the storage group, Fields collection.

If you use circular logging you will not be able to restore DB transactions that occurred after the last back up.


Fields Property

The Fields collection for the object.

[Visual Basic]
Property Fields as ADODB.Fields
read-only
[C++]
HRESULT get_Fields(Fields** pVal);
[IDL]
HRESULT [propget] Fields([out,retval] Fields** pVal);

Remarks

The Fields property obtains a collection of ADO Field objects, each of which contains a field relating to the StorageGroup object.

Note When you use the ADO Fields.Update method, field values are updated only in memory. You must call IDataSource.Save to save the changes to the Web Storage System. To get the IDataSource interface, use the GetInterface method on the CDO object.


Name Property

Returns or sets the name of the storage group.

[Visual Basic,VBScript]
Property Name as String
[C++]
HRESULT get_Name(BSTR* pVal);
HRESULT put_Name(BSTR pVal);
[IDL]
HRESULT [propget] Name([out,retval] BSTR* pVal);
HRESULT [propput] Name([in] BSTR Val);


LogFilePath Property

Gets the The JET_paramLogFilePath property.

 [Visual Basic,VBScript]
Property LogFilePath as String
read-only
[C++]
HRESULT get_LogFilePath (BSTR* pVal);
[IDL]
HRESULT [propget] LogFilePath ([out,retval] BSTR* pVal);
HRESULT [propput] LogFilePath ([in] BSTR Val);


SystemFilePath Property

Gets the JET_paramSystemFilePath property.

[Visual Basic,VBScript]
Property SystemFilePath as String
read-only
[C++]
HRESULT get_SystemFilePath (BSTR* pVal);
[IDL]
HRESULT [propget] SystemFilePath ([out,retval] BSTR* pVal);
HRESULT [propput] SystemFilePath ([in] BSTR Val);


ZeroDatabase Property

Gets or sets the JET_paramZeroDatabaseDuringBackup property.

[Visual Basic,VBScript]
Property ZeroDatabase as Boolean
[C++]
HRESULT get_ZeroDatabase (VARIANT_BOOL* pVal);
HRESULT put_ZeroDatabase (VARIANT_BOOL pVal);
[IDL]
HRESULT [propget] ZeroDatabase ([out,retval] VARIANT_BOOL* pVal);
HRESULT [propput] ZeroDatabase ([in] VARIANT_BOOL pVal);


PublicStoreDBs Property

A list of public store databases in the storage group.

[Visual Basic,VBScript]
Property PublicStoreDBs as Variant
read-only
[C++]
HRESULT get_PublicStoreDBs (VARIANT* pVal);
[IDL]
HRESULT [propget] PublicStoreDBs ([out,retval] VARIANT* pVal);

Remarks

This is an array of Strings.


MailboxStoreDBs Property

A list of mailbox store databases.

[Visual Basic,VBScript]
Property MailboxStoreDBs as Variant
read-only
[C++]
HRESULT get_MailboxStoreDBs (VARIANT* pVal);
[IDL]
HRESULT [propget] MailboxStoreDBs ([out,retval] VARIANT* pVal);

Remarks

This is an array of Strings.


GetInterface Method

Returns the specified dual interface on the object.

[Visual Basic]
Function GetInterface(ByVal Interface as String) as Object
[C++]
HRESULT GetInterface(BSTR Interface, IDispatch** pVal);
[IDL]
HRESULT GetInterface([in] BSTR Interface, [out,retval] IDispatch** pVal);
Interface
The name of interface to obtain.

Remarks

The GetInterface method is primarily intended as a generic interface navigation aid to scripting languages that do not support such navigation directly. Most COM classes that provide implementations of the IMessage interface expose additional dual interfaces that are accessible by scripting languages only through properties on the interface, such as BodyPart and DataSource, or through the GetInterface method. When properties do not exist on the interface to return these interfaces, the GetInterface method must be used.

The list of valid interface names to pass to GetInterface is dependent upon a specific implementation. As a general rule, the name of the desired interface should match the physical name of the interface as it appears in the type library or .idl file. Check the appropriate COM class for a list of exposed dual interfaces.

Example

The following examples demonstrate using GetInterface to return other interfaces on a StorageGroup object.

[VBScript]
Dim istoregroup
Dim iDsrc

'Create an instance and get IStorageGroup (IDispatch) back
Set istoregroup = CreateObject("CDOEXM.StorageGroup")

'Get IDataSource2 on the StorageGroup Object
Set iDsrc = istoregroup.GetInterface("IDataSource2")
[JScript]
var istoregroup= new ActiveXObject("CDOEXM.StorageGroup");
var iDsrc = istoregroup.GetInterface("IDataSource2");


MoveLogFiles Method

Sets or relocates the log files to a different path, or points to existing log files.

[Visual Basic,VBScript]
Function MoveLogFiles(LogFilePath As String, Optional Flags as Long)
[C++]
HRESULT MoveLogFiles(BSTR LogFilePath, long Flags);
[IDL]
HRESULT MoveLogFiles([in] BSTR LogFilePath,
                     [in,optional] long Flags);
LogFilePath
The path to the log files.
Flags
Reserved for future use.

Remarks

This changes the log file path. LogFilePath is a directory in the file system. For new objects, this will set the initial value of the LogFilePath property. For an existing object, the path can only be changed if running on the local machine.


MoveSystemFiles Method

Sets or relocates the system files to a different path, or points to existing system files.

[Visual Basic,VBScript]
Function MoveSystemFiles(SystemFilePath As String, Optional Flags as Long)
[C++]
HRESULT MoveSystemFiles(BSTR SystemFilePath, long Flags);
[IDL]
HRESULT MoveSystemFiles([in] BSTR SystemFilePath,
                        [in,optional] long Flags);
LogFilePath
The path to the system files.
Flags
Reserved for future use.

Remarks

Changes the system file path. SystemFilePath is a directory in the file system. For new objects, this will set the initial value of the SystemFilePath property. For an existing object, the path can only be changed if running on the local machine


IVariants Interface

Provides methods and properties for managing lists of variants. These lists of variants are used by properties of the IRecurrencePattern interface.

IID
CD00012F-8B95-11D1-82DB-00C04FB1625D
Extends
IDispatch

Member Summary

Properties

Name | Type | Description
Count (Read-only) | [Visual Basic,VBScript] Long [C++,IDL]Long | Returns the number of variants in the collection.
Item (Read-only) | [Visual Basic,VBScript] Long [C++,IDL]Long | Returns the variant value at the specified location in the collection.
_NewEnum (Read-only) | [Visual Basic,VBScript] (Used in For Each In) [C++,IDL] IUnknown* | Returns an IEnumVariant interface on an enumeration object. (This property is hidden from Microsoft® Visual Basic® and is used in For Each in constructs.)

Methods

Name | Description
Delete | Deletes the variant at the specified location.
Add | Adds the specified variant to the collection.


Count Property

Returns the number of variants in the collection.

[Visual Basic]
Property Count as Long
read-only
[C++]
HRESULT get_Count(long* Count);
[IDL]
[propget, id(1)] HRESULT Count([out, retval] long *Count);
Count [C++,IDL]
On return, the number of items in the collection.


Item Property

Returns the variant at the specified location in the collection.

[Visual Basic]
Property Item(Index as Long) as Long
read-only
[C++]
HRESULT get_Item(long Index, long *Value);
[IDL]
[propget, id(0)] HRESULT Item(long Index, [out, retval] long *Value);
Index
The ordinal index of the variant to retrieve.
Value[C++,IDL]
On return, the variant requested from the collection.


_NewEnum Property

Returns the variant at the specified location in the collection.

[Visual Basic]
*Used in For Each In Constructs automatically
[C++]
HRESULT get__NewEnum(IUnknown **Value);
[IDL]
[propget, restricted, id(DISPID_NEWENUM)]
HRESULT _NewEnum([out, retval] IUnknown** Unknown);
Unknown [C++, IDL]
The IUnknown interface on an object exposing the IEnumVARIANT interface.

Remarks

Call QueryInterface on the returned interface for the IEnumVARIANT (IID_IEnumVARIANT) interface on the object. You can then use this interface to enumerate the collection.

Visual Basic programmers do not use this restricted property directly. It is used automatically in For Each In constructs.


Delete Method

Deletes the specified variant from the collection.

[Visual Basic]
Sub Delete(Value as Long)
[C++]
HRESULT Delete(long *Value);
[IDL]
[id(2)] HRESULT Delete([in] long *Value);
Value
The pointer to the variant to delete.

Remarks

Note that you pass the address of the variable (ByRef), rather than the value of the variable, to the Delete method.


Add Method

Adds the specified variant to the collection.

[Visual Basic]
Sub Add(NewValue as Variant)
[C++]
HRESULT Add(VARIANT NewValue);
[IDL]
[id(3)] HRESULT Add([in] VARIANT NewValue);
NewValue
The value to add to the collection.


IWorkflowSession Interface

Provides an intrinsic object passed to actions and condition scripts.

IID
CD001025-8B95-11D1-82DB-00C04FB1625D
Extends
IDispatch

Member Summary

Properties

Name | Type | Description
ActiveConnection (Read-only) | [Visual Basic,VBScript] ADODB.Connection [C++,IDL] _Connection* | Contains the Session object of the user that initiated the event, available only in privileged mode workflows. (Read-only)
Domain (Read-only) | [Visual Basic,VBScript] String [C++,IDL]BSTR | Contains the server's domain name. (Read-only)
ErrorDescription | [Visual Basic,VBScript] String [C++,IDL]BSTR | The details of an error to be reported back to the audit trail.
ErrorNumber | [Visual Basic,VBScript] Long [C++,IDL]Long | Holds the error number to be reported back to the calling client and logged to the audit trail.
Fields (Read-only) | [Visual Basic,VBScript] Fields [C++,IDL]Fields* | The property collection for the ProcessInstance object. (Read-only)
ItemAuthors (Read-only) | [Visual Basic,VBScript] IMembers [C++,IDL] IMembers* | The collection of users allowed to modify an item, in addition to the default collection. (Read-only)
ItemReaders (Read-only) | [Visual Basic,VBScript] IMembers [C++,IDL] IMembers* | The collection of users allowed exclusive read access to an item. (Read-only)
Properties (Read-only) | [Visual Basic,VBScript] ISessionProps [C++,IDL] ISessionProps* | Returns the ISessionProps interface for the WorkflowSession object. (Read-only)
ReceivedMessage (Read-only) | [Visual Basic,VBScript] IWorkflowMessage [C++,IDL] IWorkflowMessage* | Returns a pointer to the IWorkflowMessage interface for correlated messages that initiate state transitions. (Read-only)
Sender (Read-only) | [Visual Basic,VBScript] String [C++,IDL]BSTR | Contains the SMTP address of the user that initiated the state transition. (Read-only)
Server (Read-only) | [Visual Basic,VBScript] String [C++,IDL]BSTR | Contains the server name. (Read-only)
StateFrom (Read-only) | [Visual Basic,VBScript] String [C++,IDL]BSTR | Contains the state of the process instance before the current transition. (Read-only)
StateTo (Read-only) | [Visual Basic,VBScript] String [C++,IDL]BSTR | Contains the state of the process instance after the current transition. (Read-only)
TrackingTable (Read-only) | [Visual Basic,VBScript] Recordset [C++,IDL]_Recordset* | Returns a pointer to the recordset object containing data related to the process instance that initiated the state transition. (Read-only)

Methods

Name | Description
AddAuditEntry | Provides audit trail method for script writers.
DeleteReceivedMessage | Deletes the message correlated with the ProcessInstance item.
DeleteWorkflowItem | Deletes the ProcessInstance item.
GetNewWorkflowMessage | Returns a new WorkflowMessage object.
GetUserProperty | Gets a directory attribute property of a user.
IsUserInRole | Checks if a user is in a folder role.

Remarks

IWorkflowSession specifies the intrinsic object passed to your action and condition scripts that provide run-time communication between the workflow engine, your script, and the ProcessInstance item being processed.

See Also

Developing Typical Workflow Applications

© 2000-2001 Microsoft Corporation. All rights reserved.


ActiveConnection Property

Contains the session object of the user that initiated the event. (Read-only)

[Visual Basic]
Property ActiveConnection As Connection
[C++]
HRESULT get_ActiveConnection( _Connection** varActiveConnection);
[IDL]
HRESULT ActiveConnection([out, retval] _Connection** varActiveConnection);

Remarks

You can use this property in privileged mode only. Your script gets an error message if you attempt to use this property in restricted mode.

The ActiveConnection property contains the Session object of the user that initiated the event. Your workflow script can use this property to access the Microsoft® Web Storage System in which the ProcessInstance is running. You can perform transactions in that Web Storage System only, according to the rights of the user.

If a workflow transition fails, any changes made with the ActiveConnection property are rolled back. This makes your applications more robust.

The ActiveConnection property is only valid for the Web Storage System in which the event occurred. You cannot use the ActiveConnection property for a public folder event to access a user's inbox. Also you cannot use SendUsingExchange to send a message as the user with an ActiveConnection to a public folder, because you must have access to the user's outbox.

Example

This example binds the record object to a document in a public folder tree "as the user" that initiated the state transition. Also, this example uses a file URL with the Exchange OLE DB (ExOLEDB) provider. The ExOLEDB provider also supports the HTTP URL scheme.

[Visual Basic]
'Assume rec is an ADODB Record object already created

Rec.Open "file://./backofficestorage/" _
                    & WorkflowSession.Domain _
                    & "/public folders/UserFolder/PrivateUserDocument.doc", _
                    WorkflowSession.ActiveConnection, _
                    adModeReadWrite, _
                    adFailIfNotExists

See Also

IWorkflowSession

© 2000-2001 Microsoft Corporation. All rights reserved.


Domain Property

Contains the server's domain name. (Read-only)

[Visual Basic]
Property Domain As String
[C++]
HRESULT get_Domain(BSTR* varDomain);
[IDL]
HRESULT Domain([out, retval] BSTR* varDomain);

Remarks

You can use this in your script to construct http://, file://, and LDAP:// URLs. If the script will run on the client, do not use file:// URLs, because these usually do not resolve to the correct resource.

Example

"http://" + WorkflowSession.Server + "." + WorkflowSession.Domain

See Also

IWorkflowSession

© 2000-2001 Microsoft Corporation. All rights reserved.


ErrorDescription Property

The details of an error to be reported back to the audit trail.

[Visual Basic]
Public Property strErrorDescription as String
[C++]
HRESULT get_ErrorDescription (BSTR* pVal);
HRESULT put_ErrorDescription (BSTR Val);
[IDL]
HRESULT [propget] ErrorDescription ([out,retval] BSTR* pVal);
HRESULT [propput] ErrorDescription ([in] BSTR Val);

Remarks

If the ErrorNumber property is set to a negative value, the workflow engine looks for an error description in this property. If the ErrorNumber property is not set or is set to a value greater than or equal to zero, nothing happens.

Example

The following script causes the item transition to terminate. The workflow engine adds an entry to the audit trail with the error number and description. Assuming SendMail was previously defined, it sends a message back to the user that initiated the workflow with Please vote on the subject line.

[VBScript]
If (WorkflowSession.ReceivedMessage.fields("VoteButton").Value = "") Then
   WorkflowSession.ErrorNumber = &H80004005 'Number returned to client
   WorkflowSession.ErrorDescription = "Form not completed."
   SendMail "Please vote"
End If

Sub SendMail(MySubject)
   Set WFMsg = WorkflowSession.GetNewWorkflowMessage()
   With WFMsg
      .From = WorkflowSession.Sender
      .To = WorkflowSession.Sender
      .Subject = MySubject
      .TextBody = WorkflowSession.StateFrom & " -> " & WorkflowSession.StateTo
      .SendWorkflowMessage 0 'cdowfNoTracking
   End With
End Sub

See Also

IWorkflowSession

AuditTrailProvider

© 2000-2001 Microsoft Corporation. All rights reserved.


ErrorNumber Property

Holds the error number to be reported back to the calling client and logged to the audit trail.

[Visual Basic]
Public Property ErrorNumber as Long
[C++]
HRESULT get_ErrorNumber(Long* pVal);
HRESULT put_ErrorNumber (Long Val);
[IDL]
HRESULT [propget] ErrorNumber([out,retval] Long* pVal);
HRESULT [propput] ErrorNumber ([in] Long Val);

Remarks

Upon exiting a script, the workflow engine automatically looks for an error number in this property.

Your script can terminate a transition by passing a negative number (ErrorNumber < 0) back to the workflow engine. The workflow engine logs a failure to the audit trail. Use IWorkflowSession.ErrorDescription to specify an error description to the audit trail.

If you set the ErrorNumber to a non-negative value (ErrorNumber >= 0), the workflow engine ignores it.

Example

[VBScript]
If (WorkflowSession.ReceivedMessage.fields("VoteButton").Value = "") Then
   WorkflowSession.ErrorNumber = &H80004005 'Number returned to client
   WorkflowSession.ErrorDescription = "Form not completed."
   SendMail "Please vote"
End If

Sub SendMail(MySubject)
   Set WFMsg = WorkflowSession.GetNewWorkflowMessage()
   With WFMsg
      .From = WorkflowSession.Sender
      .To = WorkflowSession.Sender
      .Subject = MySubject
      .TextBody = WorkflowSession.StateFrom & " -> " & WorkflowSession.StateTo
      .SendWorkflowMessage 0 'cdowfNoTracking
   End With
End Sub

See Also

IWorkflowSession

AuditTrailProvider

© 2000-2001 Microsoft Corporation. All rights reserved.


Fields Property

The property collection for the ProcessInstance object that initiated the WorkflowSession. (Read-only)

[Visual Basic,VBScript]
Property Fields As Fields
read-only
[C++]
HRESULT get_Fields(Fields** varFields);
[IDL]
HRESULT Fields([out, retval] Fields** varFields);

Remarks

This property is read-only in that you cannot get a Fields collection from a different item, but you can modify fields in this collection. The collection you get from the WorkflowSession object is read/write.

The WorkflowSession Fields collection maps directly to the ProcessInstance Fields collection. Use this collection to put and get properties for the ProcessInstance that initiated the session.

You cannot use the WorkflowSession Fields collection to modify ProcessInstance schema properties including the following. The workflow engine maintains strict control over these properties.

  • "http://schemas.microsoft.com/cdo/workflow/currentstate"
  • "http://schemas.microsoft.com/cdo/workflow/expirytime"
  • "http://schemas.microsoft.com/cdo/workflow/processdefinition"
  • "http://schemas.microsoft.com/cdo/workflow/trackingtablexml"

Note When you use the ADO Fields.Update method, field values are updated only in memory. You must call IDataSource.Save to save the changes to the Web Storage System. To get the IDataSource interface, use the GetInterface method on the CDO object.

Example

You can use the WorkflowSession Fields collection in an assignment for only your custom properties. The following works, for example:

[VBScript]
...
workflowsession.Fields("YourNameSpace://workflow/yourcustomproperty") = "yourPropValue"

See Also

IWorkflowSession

IItem.Fields

© 2000-2001 Microsoft Corporation. All rights reserved.


ItemAuthors

The collection of users allowed to modify and delete an item.

[Visual Basic]
Property ItemAuthors As IMembers
[C++]
HRESULT get_ItemAuthors( IMembers** varItemAuthors);
[IDL]
[propget]
HRESULT ItemAuthors([out, retval] IMembers** varItemAuthors);

Remarks

You can use this collection to maintain per-item modify and delete privileges. When the collection has members, only members of the collection can modify or delete an item. This allows you to give certain users or groups temporary exclusive author access to an item. When this collection is empty, the default author privileges for the folder apply. This collection uses the properties and methods of the IMembers interface.

See Also

ItemReaders

IMembers

© 2000-2001 Microsoft Corporation. All rights reserved.


ItemReaders

The collection of users allowed exclusive read access to an item.

[Visual Basic]
Property ItemReaders As IMembers
read-only
[C++]
HRESULT get_ItemReaders ( IMembers** varItemAuthors);
[IDL]
[propget]
HRESULT ItemReaders ([out, retval] IMembers** varItemAuthors);

Remarks

You can use this collection to maintain per-item read access privileges. When the collection has members, only members of the collection can read an item. This allows you to give certain users or groups temporary exclusive read access to an item. When this collection is empty, the default read privileges for the folder apply. This collection uses the properties and methods of the IMembers interface.

See Also

ItemAuthors

IMembers

© 2000-2001 Microsoft Corporation. All rights reserved.


Properties Property

Returns the ISessionProps interface for the WorkflowSession object.

[Visual Basic]
Property Properties as ISessionProps
read-only
[C++]
HRESULT get_Properties(ISessionProps* pVal);
[IDL]
HRESULT [propget] Properties([out,retval] ISessionProps* pVal);

Remarks

This property returns a read-only pointer to the ISessionProps interface, which you can use for persisting custom properties within a session. While the pointer is read-only, the interface allows you to read and write properties to the underlying ProcessInstance row in the Exchange Web Storage System. This enables you to access those properties from several function calls within a session. A session lasts for only one ProcessInstance transition.

See Also

IWorkflowSession

ISessionProps

© 2000-2001 Microsoft Corporation. All rights reserved.


ReceivedMessage Property

Returns a pointer to the IWorkflowMessage interface for correlated messages that initiate state transitions. (Read-only)

[Visual Basic,VBScript]
Property ReceivedMessage As WorkflowMessage
[C++]
HRESULT get_ReceivedMessage(IWorkflowMessage** varReceivedMessage);
[IDL]
[propget]
HRESULT ReceivedMessage([out, retval] IWorkflowMessage** varReceivedMessage);

Remarks

When a message arrives in a folder in response to an existing workflow process, the workflow engine correlates it with the ongoing process and makes an entry in the TrackingTable. n this case, ReceivedMessage returns a pointer to the correlated message. If a new workflow is initiated by e-mail, the workflow engine creates a new ProcessInstance and the ReceivedMessage property returns nothing.

(Read-only)

Example

The following procedure takes the value in the response field of the reply form and puts in the response field of the workflow item.

[VBScript]
<ue>wfProgTasks_updWfItem</ue>

See Also

IWorkflowSession

IWorkflowMessage

© 2000-2001 Microsoft Corporation. All rights reserved.


Sender Property

Contains the SMTP address of the user that initiated the state transition.

[Visual Basic,VBScript]
Public Property Sender as String
[C++]
HRESULT get_Sender (BSTR* pVal);
 [IDL]
[propget]
HRESULT Sender ([out,retval] BSTR* pVal);

Remarks

When a user posts an item to your workflow folder, the SMTP address goes in this WorkflowSession property.

Example

[VBScript]
Sub SendMail(MySubject)
   Set WFMsg = WorkflowSession.GetNewWorkflowMessage()
   With WFMsg
      .From = WorkflowSession.Sender
      .To = WorkflowSession.Sender
      .Subject = MySubject
      .TextBody = WorkflowSession.StateFrom & " -> " & WorkflowSession.StateTo
      .SendWorkflowMessage 0 'cdowfNoTracking
   End With
End Sub

See Also

IWorkflowSession

© 2000-2001 Microsoft Corporation. All rights reserved.


Server Property

Contains the server name.

[Visual Basic,VBScript]
Property Server As String
read-only
[C++]
HRESULT get_Server(BSTR* varServer);
[IDL]
[propget]
HRESULT Server([out, retval] BSTR* varServer);

Remarks

You can use this in your script to construct http://URLs, file://URLs, and LDAP://URLs.

Example

"http://" + WorkflowSession.Server + "." + WorkflowSession.Domain

See Also

IWorkflowSession

© 2000-2001 Microsoft Corporation. All rights reserved.


StateFrom Property

Contains the state of the process instance before a transition.

[Visual Basic]
Property StateFrom as String
read-only
[C++]
HRESULT get_StateFrom(BSTR* pVal);
[IDL]
[propget]
HRESULT StateFrom([out,retval] BSTR* pVal);

Remarks

The value of this property might be null depending on the type of transition this process instance represents.

Example

This example uses the StateFrom property in a condition script that prevents an action from firing if the transition is not a state change.

[VBScript]
function CheckNewState()
   if workflowsession.statefrom <> workflowsession.stateto then
          CheckNewState= true
   else
          CheckNewState= false
   end if
end function

See Also

IWorkflowSession

CurrentState

© 2000-2001 Microsoft Corporation. All rights reserved.


StateTo Property

Contains the state of the process instance after a transition.

[Visual Basic]
Property StateTo as String
read-only
[C++]
HRESULT get_StateTo(BSTR* pVal);
[IDL]
[propget]
HRESULT StateTo([out,retval] BSTR* pVal);

Remarks

The value of this property might be null depending on the type of transition this process instance represents.

Example

This example uses the StateTo property to fill the TextBody of a WorkflowMessage object. The workflow engine passes the WorkflowSession intrinsic object to the script host, so you do not have to create it explicitly.

[VBScript]
Sub SendMail(MySubject)
   Set WFMsg = WorkflowSession.GetNewWorkflowMessage()
   With WFMsg
      .From = WorkflowSession.Sender
      .To = WorkflowSession.Sender
      .Subject = MySubject
      .TextBody = WorkflowSession.StateFrom & " -> " & WorkflowSession.StateTo
      .SendWorkflowMessage 0 'cdowfNoTracking
   End With
End Sub

See Also

IWorkflowSession

CurrentState

© 2000-2001 Microsoft Corporation. All rights reserved.


TrackingTable Property

Returns a pointer to the recordset object containing e-mail data related to the process instance that initiated the state transition. (Read-only)

[Visual Basic,VBScript]
Property TrackingTable As ADODB.Recordset
read-only
[C++]
HRESULT get_TrackingTable(_Recordset** varTrackingTable);
[IDL]
[propget]
HRESULT TrackingTable([out, retval] _Recordset** varTrackingTable);

Remarks

The workflow engine uses the TrackingTable to store information regarding e-mail messages correlated with a ProcessInstance. If the engine matches a row in the ActionTable with an OnReceive event, it makes an entry in the TrackingTable for the ReceivedMessage.

The tracking table provides you with ten fields that you can use to store additional properties you may want to track. These are the custom0 through custom9 fields.

Records in the TrackingTable have the following fields.

Field Name | Type | Maximum Size | May be NULL
email | WCHAR | 512 characters | No
trackingid | WCHAR | 512 characters | Yes
date | WCHAR | 512 characters | No
state | WCHAR | 512 characters | No
flags | WCHAR | 512 characters | No
response | WCHAR | 512 characters | Yes
custom0 - custom9 | WCHAR | 512 characters | Yes

TrackingTable Field Semantics
email
This contains the address in the To field of outgoing forms or messages.
trackingid
This is a GUID created by the workflow engine when you use SendWorkflowMessage(). The engine uses this GUID to correlate all subsequent messages associated with the ProcessInstance.
date
For outgoing messages, this is the sent time. For incoming messages, this is the received time.
state
The workflow engine puts the state of the ProcessInstance here when you use SendWorkflowMessage(). It puts the ProcessInstance state in this field for all correlated responses as well.
flags
This can be 'cdowfStrict', 'cdowfAdd', or 'cdowfNoTracking'. When you use SendWorkflowMessage(cdowfStrict), the engine puts 'cdowfStrict' in this field.
response
The workflow engine automatically copies the value of the form field "http://schemas.microsoft.com/cdo/workflow/response" into this column; you do not need to write any code.
custom0 - custom9
These are ten fields that you can use to store data from your form. You need to write the script code to copy the data to the TrackingTable.

Example

The function checks all the records in the TrackingTable for a match between the response sender and the email field of the table. If it finds an address match, it checks to see if the value in the table's state field matches the state in the current ActionTable row from which this script was called. If both match, it adds a value to a custom property field in the TrackingTable. The following example uses the TrackingTable property in a script function:

[VBScript]
Sub AddProp()

WorkflowSession.TrackingTable.MoveFirst

For i = 0 To WorkflowSession.TrackingTable.RecordCount - 1 Step 1

   If WorkflowSession.Sender = WorkflowSession.TrackingTable.fields("email").Value Then
      WorkflowSession.AddAuditEntry "email address matched"

      If "A" = WorkflowSession.TrackingTable.fields("state").Value Then
         'The state value here is hard coded you will have to
         'change this for your own action table
         WorkflowSession.AddAuditEntry "state matched"

         WorkflowSession.TrackingTable.fields.Item("custom0").Value = WorkflowSession.ReceivedMessage.fields("Amount").Value

         WorkflowSession.AddAuditEntry "added the value to the customfield"
         WorkflowSession.TrackingTable.Update
      End If
   End If
   WorkflowSession.TrackingTable.MoveNext
Next
WorkflowSession.DeleteReceivedMessage

End Sub

See Also

IWorkflowSession

IWorkflowMessage

SendWorkflowMessage

© 2000-2001 Microsoft Corporation. All rights reserved.


AddAuditEntry Method

Provides an Audit Trail method for script writers.

[Visual Basic,VBScript]
Sub AddAuditEntry (bsDescription As String, [hResult As Long])
[C++]
HRESULT AddAuditEntry(
                BSTR bsDescription,
                long hResult);
[IDL]
HRESULT AddAuditEntry(
                [in] BSTR bsDescription,
                [in, optional, defaultvalue(0)] long hResult);

Remarks

The AddAuditEntry method maps to the IAuditTrail AddEntry method. AddAuditEntry tells the workflow engine to call AddEntry using bsDescription and hResult as the first two parameters in AddEntry. AddEntry writes the bsDescription string to the current AuditTrailProvider.

Example

[VBScript]
WorkflowSession.AddAuditEntry "My error/information message..."

See Also

IWorkflowSession

© 2000-2001 Microsoft Corporation. All rights reserved.


DeleteReceivedMessage Method

Deletes the message correlated with the ProcessInstance item.

[Visual Basic,VBScript]
Sub DeleteReceivedMessage()
[C++]
HRESULT DeleteReceivedMessage();
[IDL]
HRESULT DeleteReceivedMessage();

Remarks

You can only call this method for the OnReceive event. This method deletes the message that was correlated with ProcessInstance.

Example

[VBScript]
'OnReceive event in ActionTable
'Action Script Procedure:
WorkflowSession.DeleteReceivedMessage

See Also

IWorkflowSession

ReceivedMessage

© 2000-2001 Microsoft Corporation. All rights reserved.


DeleteWorkflowItem Method

Deletes the ProcessInstance item.

[Visual Basic,VBScript]
Sub DeleteWorkflowItem()
[C++]
HRESULT DeleteWorkflowItem();
[IDL]
HRESULT DeleteWorkflowItem();

Remarks

You can call this method from your script for the following event types:

  • OnChange
  • OnCreate
  • OnDelete
  • OnExpiry

This method deletes the ProcessInstance row from the Exchange Web Storage System, but the workflow event sink will not invoke the workflow engine with an OnDelete event. If you want to take special action when deleting a ProcessInstance, do it before or after calling DeleteWorkflowItem.

Example

[VBScript]
'Action Script Procedure:
WorkflowSession.DeleteWorkflowItem

See Also

IWorkflowSession

IProcessInstance

© 2000-2001 Microsoft Corporation. All rights reserved.


GetNewWorkflowMessage Method

Returns a new WorkflowMessage object.

[Visual Basic,VBScript]
Function GetNewWorkflowMessage() As IWorkflowMessage
[C++]
HRESULT GetNewWorkflowMessage(IWorkflowMessage** ppWorkflowMessage);
[IDL]
HRESULT GetNewWorkflowMessage([out, retval] IWorkflowMessage** ppWorkflowMessage);

Remarks

This method enables script access to the WorkflowMessage object. The WorkflowMessage object provides message sending and tracking ability per ProcessInstance through its SendWorkflowMessage method.

Example

This example illustrates the use of the GetNewWorkflowMessage method. This is a member method of the WorkflowSession intrinsic object. You do not have to create the WorkflowSession object because the workflow engine passes it to the script host. GetNewWorkflowMessage returns a WorkflowMessage object. As a result, the script can use the IWorkflowMessage interface to set the 'From', 'To', 'Subject', and 'TextBody' fields, as well as send the message.

[VBScript]
Sub SendMail(MySubject)
   Set WFMsg = WorkflowSession.GetNewWorkflowMessage()
   With WFMsg
      .From = WorkflowSession.Sender
      .To = WorkflowSession.Sender
      .Subject = MySubject
      .TextBody = WorkflowSession.StateFrom & " -> " & WorkflowSession.StateTo
      .SendWorkflowMessage 0 'cdowfNoTracking
   End With
End Sub

See Also

IWorkflowSession

IWorkflowMessage

© 2000-2001 Microsoft Corporation. All rights reserved.


GetUserProperty

Gets a directory attribute property of an Active Directory™ object.

[Visual Basic,VBScript]
Function GetUserProperty(bsUser As String, _
                         bsAttrName As String, _
                         bIsEmail As UserIDType)
[C++]
HRESULT GetUserProperty(
                        BSTR bsUser,
                        BSTR bsAttrName,
                        UserIDType bIsEmail,
                           VARIANT* varAttr);
[IDL]
HRESULT GetUserProperty(
                        [in] BSTR bsUser,
                        [in] BSTR bsAttrName,
                        [in] UserIDType bIsEmail,
                           [out, retval] VARIANT* varAttr);
bsUser
Distiniguished Name in Active Directory if bIsEmail equals cdowfDistinguishedName(1) or e-mail address if bIsEmail equals cdowfUserEmailAddress(0).
bsAttrName
Active Directory attribute.
bIsEmail
cdowfUserEmailAddress(0) if bsUser is an e-mail address or cdowfDistinguishedName(1) if bsUser is a distinguished name from Active Directory.

Example

[VBScript]
'Action Script Procedure:
mgr = GetUserMgr ("someone@microsoft.com")

Function GetUserMgr (UserAddress)
   with WorkflowSession
      mgrDN = .GetUserProperty(UserAddress,  "manager",0)
      GetUserMgr = .GetUserProperty(mgrDN, "mail", 1)
   end with
End Function

See Also

IWorkflowSession

© 2000-2001 Microsoft Corporation. All rights reserved.


IsUserInRole

Checks if a user is in a folder role.

[Visual Basic,VBScript]
Function IsUserInRole(bsUser As String, _
                      bsRole As String) _
                      As Boolean
[C++]
HRESULT IsUserInRole(
                      BSTR bsUser,
                      BSTR bsRole,
                      VARIANT_BOOL* bIsMember);
[IDL]
HRESULT IsUserInRole(
                [in] BSTR bsUser,
                [in] BSTR bsRole,
                [out, retval] VARIANT_BOOL* bIsMember);
bsUser
The user's User Principal name (UPN).
bsRole
The name of the role. There are sixteen valid fixed strings for your use. Valid strings include "Role1", "Role2", ... , "Role16".

Example

[VBScript]
WorkflowSession.IsUserInRole ("someone@microsoft.com", "Role9")

See Also

IWorkflowSession

© 2000-2001 Microsoft Corporation. All rights reserved.


IWorkflowMessage Interface

Supports authoring of restricted workflow scripts.

IID
CD001024-8B95-11D1-82DB-00C04FB1625D
Extends
IDispatch

Member Summary

Properties

Name | Type | Description
Attachments (Read-Only) | [Visual Basic] IBodyParts [C++,IDL] IBodyParts * | Returns the collection of attachments for this message.
AutoGenerateTextBody | [Visual Basic] Boolean [C++,IDL] VARIANT_BOOL | Indicates whether the TextBody of a message should automatically be generated from the contents of the HTMLBody property for a multipart/alternative message.
BCC | [Visual Basic] String [C++,IDL] BSTR | The blind copy (Bcc) recipients for this message.
BodyPart (Read-Only) | [Visual Basic] IBodyPart [C++,IDL] IBodyPart * | Returns the IBodyPart interface on this object.
CC | [Visual Basic] String [C++,IDL] BSTR | Contains a list of copy (Cc) recipients for this message.
Configuration | [Visual Basic]Configuration [C++,IDL] IConfiguration* | An IConfiguration interface reference to a Configuration object. This object defines the messaging configuration used by the Message object.
EnvelopeFields (Read-Only) | [Visual Basic] ADODB.Fields [C++,IDL] Fields* | A collection of fields associated with the SMTP or NNTP transport envelope of the message.
Fields (Read-Only) | [Visual Basic] ADODB.Fields [C++,IDL] Fields* | Returns the collection of Fields for this object.
FollowUpTo | [Visual Basic] String [C++,IDL] BSTR | Specifies which newsgroups any responses to this message should be posted to.
From | [Visual Basic] String [C++,IDL] BSTR | Contains the messaging address of the principal author of this message.
HTMLBody | [Visual Basic] String [C++,IDL] BSTR | Contains the HTML representation of the body of this message.
HTMLBodyPart (Read-Only) | [Visual Basic] IBodyPart [C++,IDL] IBodyPart* | Returns a reference to a BodyPart object in which the HTML content of this message is stored.
Keywords | [Visual Basic] String [C++,IDL] BSTR | Contains a list of keywords assigned to this message.
MIMEFormatted | [Visual Basic] Boolean [C++,IDL] VARIANT_BOOL | Indicates whether this message is to be formatted as multipart/alternative.
Newsgroups | [Visual Basic] String [C++,IDL] BSTR | Specifies which newsgroups this message belongs to.
Organization | [Visual Basic] String [C++,IDL] BSTR | Contains a description of the organization the sender belongs to.
ReceivedTime (Read-Only) | [Visual Basic] Date [C++,IDL] DATE | Returns the date/time this message was delivered to the server.
ReplyTo | [Visual Basic] String [C++,IDL] BSTR | Contains the messaging address to which replies to this message should be sent.
Sender | [Visual Basic] String [C++,IDL] BSTR | Contains the messaging address of the submitter of this message.
SentOn (Read-Only) | [Visual Basic] Date [C++,IDL] DATE | Returns the date/time this message was submitted to the server.
Subject | [Visual Basic] String [C++,IDL] BSTR | Contains the subject of this message.
TextBody | [Visual Basic] String [C++,IDL] BSTR | Contains the plain text representation of the body of this message.
TextBodyPart (Read-Only) | [Visual Basic] IBodyPart [C++,IDL] IBodyPart * | Returns a body part object containing the text content of this message.
To | [Visual Basic] String [C++,IDL] BSTR | Contains a list of principal (To) recipients for this message.

Methods

Name | Description
AddAttachment | Adds an attachment to this message.
AddRelatedBodyPart | Adds an MHTML-related body part to the message's content.
CreateMHTMLBody | Converts the contents of an entire Web page into MHTML-formatted body parts on this message
GetStream | Returns the Stream object containing the complete message, including headers and all content, in serialized (wire-transport) format.
Post | Submits this message to the specified newsgroups.
Send | Sends the message. Does not add to tracking table.
SendWorkflowMessage | Provides a Send method when the user does not have Windows® 2000 credentials. Adds to tracking table. Unique to workflow.

Remarks

IWorkflowMessage contains a subset of the COM class CDO.Message. It does not support all the methods and properties of IMessage for security reasons. IWorkflowMessage forwards calls to common methods and properties to the IMessage object. You will be linked directly to the documentation for IMessage properties and methods where appropriate.

IWorkflowMessage exposes two methods for sending e-mail. The SendWorkflowMessage method is the preferred method for sending e-mail in workflow, because SendWorkflowMessage:

  • Supports transactions, response tracking, and MAPI properties.
  • Configures the message correctly.

IWorkflowMessage exposes the IMessage Send method as an alternative e-mail sending method in workflow. You may wish to use Send for:

  • SMTP mail to non-Exchange 2000 servers.
  • Posts to an NNTP server.

Send will fail unless you use the correct Configuration.

Example

You cannot create a WorkflowMessage object directly. Use the WorkflowSession object to get a WorkflowMessage object.

[Visual Basic]
Dim WfMsg
WfMsg = WorkflowSession.GetNewWorkflowMessage()
'Do something with WfMsg

See Also

IMessage Interface

GetNewWorkflowMessage

© 2000-2001 Microsoft Corporation. All rights reserved.


SendWorkflowMessage Method

Provides a method to send messages that support response tracking, MAPI properties, and transactional e-mail.

[Visual Basic]
Sub SendWorkflowMessage(eSendFlags As CdoWfSendFlags)
[C++]
HRESULT SendWorkflowMessage(CdoWfSendFlags eSendFlags);
[IDL]
HRESULT SendWorkflowMessage([in] CdoWfSendFlags eSendFlags);
eSendFlags
A cdoWfSendFlags constant defining workflow engine tracking behavior for responses to a sent message.

Remarks

You can use both the Send and SendWorkflowMessage methods in workflow, but only SendWorkflowMessage supports response tracking, transactional e-mail, and MAPI properties.

SendWorkflowMessage sets the following in the Configuration object:

  • From = Workflow Event Sink account address.
  • ReplyTo = Workflow folder address, unless eSendFlags = cdoWfNoTracking (0), then ReplyTo = "" and can be modified by script.
  • cdoSendUsingMethod = cdoSendUsingExchange.

SendWorkflowMessage has the following restrictions:

  • SendWorkflowMessage can only be used with a folder that is mail-enabled. You will get a CDOWF_CANT_OBTAIN_FOLDERADDR error if you try to call it from a folder that is not mail-enabled.
  • SendWorkflowMessage requires that the Workflow Event Sink account have a valid mailbox and that the To field contain a valid address.
  • SendWorkflowMessage cdowfAdd|cdowfStrict cannot be used with an OnCreate event in a script action or condition. You will get a CDOWF_NO_PERM_URL error if you try this in an OnCreate event. SendWorkflowMessage cdowfNoTracking works in an OnCreate event.
  • You can use SendWorkflowMessage in a CompensatingAction, but SendWorkflowMessage behaves differently in a CompensatingAction. In the case of a CompensatingAction, SendWorkflowMessage will send the message immediately, and the message will not be part of a transaction.

Example

The following example uses the WorkflowSession object to get a WorkflowMessage object and sends a message to the user that initiated the state transition with the response tracking turned off.

[Visual Basic]
Dim WfMsg
Set WfMsg = WorkflowSession.GetNewWorkflowMessage()
With WfMsg
   .To = WorkflowSession.Sender
   .Subject = "SendWorkflowMessage Test"
   .SendWorkflowMessage cdowfNoTracking
End With

See Also

IWorkflowMessage Interface

CdoWfSendFlags Enum

© 2000-2001 Microsoft Corporation. All rights reserved.


OLE DB Row Access

By using C or C++ you can get a pointer to the following OLE DB interfaces from several CDO COM classes:

OLE DB Interfaces | Accessible From
IRow IRowChange IRowSchemaChange IColumnsInfo IColumnsInfo2 | Addressee Appointment BodyPart CalendarMessage CalendarPart Configuration Exception Folder Item Message Person ProcessDefinition ProcessInstance

Note These interfaces are not based on Idispatch, therefore they cannot be used by clients that require automation such as scripting engines and by Microsoft® Visual Basic®.


Enumerations

The topics in this section describe the enumerations for CDO for Exchange 2000 Server (CDOEX), CDO for Exchange Management (CDOEXM), and Collaboration Data Objects Workflow (CDOWF).

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


CdoAttendeeRoleValues Enum

The CdoAttendeeRoleValues enumeration is used with the IAttendee.Role property and indicates the attendee's role for the meeting.

Name | Value | Description
cdoRequiredParticipant | 0 | This attendee is required.
cdoOptionalParticipant | 1 | This attendee is optional.
cdoNonParticipant | 2 | This attendee is copied for information purposes only.
cdoChair | 3 | This attendee is the meeting chair.

See Also

IAttendee.Role

© 2000-2001 Microsoft Corporation. All rights reserved.


CdoAttendeeStatusValues Enum

The CdoAttendeeStatusValues enumeration is used with the IAttendee.Status property and indicates the current status of a meeting attendee.

Name | Value | Description
cdoAccepted | 0 | The attendee has accepted the meeting request.
cdoDeclined | 1 | The attendee has declined the meeting request.
cdoAttendeeStatusTentative | 2 | The attendee has tentatively accepted the meeting request.
cdoNeedsAction | 3 | A response has not been received.
cdoDelegated | 4 | The requested attendee has delegated the meeting request to someone else.
cdoInprogress | 5 | The attendee has accepted the meeting request.
cdoInprogress | 6 | The requested attendee has delegated the meeting request to someone else.

See Also

IAttendee.Status

© 2000-2001 Microsoft Corporation. All rights reserved.


CdoComponentType Enum

The CdoComponentType enumeration is used with the ICalendarPart.ComponentType property to indicate whether the body part is an appointment.

Name | Value | Description
cdoComponentTypeUnknown | 0 | The object type is unknown.
cdoComponentTypeAppointment | 1 | The object is an appointment.

The ICalendarPart.ComponentType property is read-only.

See Also

ICalendarPart.ComponentType

© 2000-2001 Microsoft Corporation. All rights reserved.


CdoConfigSource Enum

The CdoConfigSource enumeration is used with the IConfiguration.Load method to specify what set of values the object should load.

Name | Value | Description
cdoDefaults | -1 | Load all applicable default field values.
cdoIIS | 1 | Load any default values using Internet Information Services (IIS).
cdoOutlookExpress | 2 | Load default values from Outlook® Express.
cdoDirectory | 3 | Load the settings located at the specified directory URL.


CdoDayOfWeek Enum

The CdoDayOfWeek enumeration is used to set the IRecurrencePattern::FirstDayOfWeek property.

Name | Value | Description
cdoSunday | 0 | Sunday
cdoMonday | 1 | Monday
cdoTuesday | 2 | Tuesday
cdoWednesday | 3 | Wednesday
cdoThursday | 4 | Thursday
cdoFriday | 5 | Friday
cdoSaturday | 6 | Saturday


CdoDSNOptions Enum

The CdoDSNOptions enumeration is used in conjunction with the IMessage::DSNOptions property to set delivery status notification (DSN) status flags for the message.

Name | Value | Description
cdoDSNDefault | 0 | No DSN commands are issued.
cdoDSNNever | 1 | No DSN commands are issued.
cdoDSNFailure | 2 | Return a DSN if delivery fails.
cdoDSNSuccess | 4 | Return a DSN if delivery succeeds.
cdoDSNDelay | 8 | Return a DSN if delivery is delayed.
cdoDSNSuccessFailOrDelay | 14 | Return a DSN if delivery succeeds, fails, or is delayed.


CdoEventStatus Enum

The CdoEventStatus enumeration is used when implementing a transport event sink using CDO. The second argument to the various event interface methods, such as ISMTPOnArrival::OnArrival and INNTPOnPost::OnPost, is set to this enumeration type. Event sinks signal to the event source whether to continue running subsequent sinks, or to skip all remaining sinks and return.

Name | Value | Description
cdoRunNextSink | 0 | Proceed to run the next sink.
cdoSkipRemainingSinks | 1 | Skip (do not notify) any remaining sinks.

Remarks

SMTP and NNTP transport event sinks are processed by the event source in serialized fashion. In other words, each sink has a priority relative to others for a particular event, and the sinks are notified one at a time. The event source proceeds from the highest priority sink to the lowest, and for each sink, it checks the returned CdoEventStatus value. If the sink sets the value to cdoSkipRemainingSinks, then the event source does not proceed to notify any lower priority (remaining) sinks.

For more information, see one of the following event-related interfaces:

ISMTPOnArrival

INNTPOnPost

INNTPOnPostFinal

INNTPOnPostEarly

For information about implementing SMTP and NNTP transport event sinks, see SMTP/NNTP Transport Event Sinks with CDO.


CDOEXMDeliverAndRedirect Enum

The CDOEXMDeliverAndRedirect enumeration is used to specify when mail is forwarded to an alternative address.

Name | Value | Description
cdoexmRecipientOrForward | 0 | Deliver mail to alternate only when mail cannot be delivered to recipient.
cdoexmDeliverToBoth | 1 | Deliver mail to both recipient and alternate.

Remarks

This type is used by the IMailRecipient::ForwardingStyle property.


CDOEXMFolderTreeType Enum

The CDOEXMFolderTreeType enumeration specifies the type of folder tree being used in a public store.

Name | Value | Description
cdoexmGeneralPurpose | 0 | Non-MAPI public folder tree
cdoexmMAPI | 1 | MAPI public folder tree
cdoexmNNTPOnly | 2 | NNTP folder tree

Remarks

This is used in the IFolderTree Interface.


CDOEXMRestrictedAddressType Enum

The CDOEXMRestrictedAddressType enumeration is used to set the IMailRecipient::RestrictedAddressList property.

Name | Value | Description
cdoexmAccept | 0 | The list contains the accepted addresses for the recipient. All other addresses were rejected.
cdoexmReject | 1 | The list contains the rejected addresses for the recipient. All other addresses were accepted.

Remarks

This type is used by the IMailRecipient::RestrictedAddresses property.


CDOEXMServerType Enum

The CDOEXMServerType enumeration is used to define the type of server.

Name | Value | Description
cdoexmFrontEnd | 0 | A front-end server.
cdoexmBackEnd | 1 | A back-end server.

Remarks

Front-end servers function as visible servers to clients such as POP, IMAP, or HTTP. Front-end servers proxy protocols to back-end servers that have the actual stores.

This enumeration is used in the ServerType property of the IExchangeServer Interface.

Note The server type is back-end by default. Changing a server to front-end cannot be undone.


CDOEXMStoreDBStatus Enum

The CDOEXMStoreDBStatus enumeration is indicates if the store is on-line or off-line.

Name | Value | Description
cdoexmOnline | 0 | Store is running.
cdoexmOffline | 1 | Store is not running.
cdoexmMounting | 2 | Reserved for future use.
cdoexmDismounting | 3 | Reserved for future use.

Remarks

This enumeration is used in the Status property of the IPublicStoreDB and the IMailboxStoreDB interfaces.


CdoFileAsMappingID Enum

The CdoFileAsMappingID enumeration defines values used to define how the text in the IPerson.FileAs property is to be generated. Use this enumeration to set the IPerson.FileAsMapping property.

Name | Value | Description
cdoMapToNone | 0 | No construction. The FileAs property is not generated. The value must be set explicitly and is not changed.
cdoMapToLastFirst | 1 | sn, givenname middlename
cdoMapToFirstLast | 2 | givenname middlename sn
cdoMapToOrg | 3 | o
cdoMapToLastFirstOrg | 4 | sn, givenname , middlename, o
cdoMapToOrgLastFirst | 5 | o, givenname, sn, middlename


CdoFolderTree Enum

Name | Value | Description
cdoGeneralPurpose | 0 | Non-MAPI public folder tree
cdoMAPI | 1 | MAPI public folder tree
cdoNNTPOnly | 2 | NNTP top-level folder.


CdoFrequency Enum

The CdoFrequency enumeration is used with the IRecurrencePattern::Frequency property exposed by instances of the RecurrencePattern COM class to define the frequency of a recurring appointment.

Name | Value | Description
cdoSecondly | 1 | The event happens once a second.
cdoMinutely | 2 | The event happens once a minute.
cdoHourly | 3 | The event happens once an hour.
cdoDaily | 4 | The event happens once a day.
cdoWeekly | 5 | The event happens once a week.
cdoMonthly | 6 | The event happens once a month.
cdoYearly | 7 | The event happens once a year.


CdoGenderValues Enum

The CdoGenderValues enumeration defines values used to specify a person's gender.

Name | Value | Description
CdoGenderUnspecified | 0 | Information not available
CdoFemale | 1 | Female
CdoMale | 2 | Male


CdoImportanceValues Enum

The CdoImportanceValues enumeration is used to set the urn:schemas:httpmail:importance field.

Name | Value | Description
cdoLow | 0 | Low importance.
cdoNormal | 1 | Normal importance.
cdoHigh | 2 | High importance.


CdoInstanceType Enum

The CdoInstanceType enumeration is used with the urn:schemas:calendar:instancetype property and indicates an appointment's instance type.

Name | Value | Description
cdoSingle | 0 | This is a single appointment.
cdoMaster | 1 | This is the master recurring appointment.
cdoInstance | 2 | This is a single instance of a recurring appointment.
cdoException | 3 | This is an exception to a recurring appointment.

See Also

urn:schemas:calendar:instancetype


CdoMailingAddressIDValues Enum

The CdoMailinbAddressIDValues enumeration defines how a person's mailing address is generated. Use the CdoMailingAddressIDValues enumeration to set the IPerson.MailingAddressID property. When set, the IPerson.MailingAddress property is generated from other mailing information in the CDO Person object. If the IPerson.MailingAddressID property set to cdoNoAddress, the mailing address is not automatically generated, and must be set manually.

Name | Value | Description
cdoNoAddress | 0 | The mailing entries are not constructed from other entries (they should be empty), and the mailing address must be manually specified.
cdoHomeAddress | 1 | The mailing entries are constructed from the home address entries of the contact.
cdoBusinessAddress | 2 | The mailing entries are constructed from the work address entries of the contact.
cdoOtherAddress | 3 | The mailing entries are constructed from the other address entries of the contact.


CdoMessageStat Enum

The CdoMessageStat enumeration is used within transport event sinks to set the http://schemas.microsoft.com/cdo/smtpenvelope field value.

Name | Value | Description
cdoStatSuccess | 0 | Success. Deliver message.
cdoStatAbortDelivery | 2 | Discard message and do not deliver.
cdoStatBadMail | 3 | Do not deliver message and place it in the bad mail directory.

Remarks

This enumeration is only used within SMTP transport event sinks created using CDO. For more information, see SMTP/NNTP Transport Event Sinks with CDO.


CdoMHTMLFlags Enum

The CdoMHTMLFlags enumeration is used to set an argument when calling the IMessage::CreateMHTMLBody method.

Name | Value | Description
cdoSuppressNone | 0 | Download all resources from the Web page (default).
cdoSuppressImages | 1 | Do not download resources from <IMG [DYN]SRC=...> or <BODY BACKGROUND=...> tags.
cdoSuppressBGSounds | 2 | Do not download resources from <BGSOUND SRC=...> tags.
cdoSuppressFrames | 4 | Do not download resources from <FRAME SRC=...> tags.
cdoSuppressObjects | 8 | Do not download resources from <OBJECT CODEBASE=...> tags.
cdoSuppressStyleSheets | 16 | Do not download resources from <LINK HREF=…> tags.
cdoSuppressAll | 31 | Do not download any resources referred to from within the page.

Remarks

You can OR (|) these enumerated values together when setting the argument. See IMessage::CreateMHTMLBody for more information.


CdoNNTPProcessingField Enum

The CdoNNTPProcessingField enumeration is used from within NNTP OnPost and OnPostEarly event sinks to set or update the value of the http://schemas.microsoft.com/cdo/nntpenvelope/nntpprocessing field.

Name | Value | Description
cdoPostMessage | 1 | Post the message.
cdoProcessControl | 2 | Send the message through control process.
cdoProcessModerator | 4 | Send the message to the moderator.

Remarks

For more information about writing NNTP service event sinks, see SMTP/NNTP Transport Event Sinks with CDO.


CdoPatternEndType Enum

The CdoPatternEndType enumeration is used to set the values of the EndType property of the IRecurrencePattern interface. It specifies how a recurring meeting pattern ends.

Name | Value | Description
cdoNoEndDate | 0 | The pattern never ends.
cdoEndByInstances | 1 | The pattern ends after a specified number of instances.
cdoEndByDate | 2 | The pattern ends after a specified date and time.

You must first specify the number of instances for the pattern using the IRecurrencePattern.Instances property, if you plan to set the EndType property to cdoEndByInstances. If you do not specify the number of instances first, CDO raises an error.

You must first specify the recurrence end date using the IRecurrencePattern.PatternEndDate property, if you plan to set the EndType property to cdoEndByDate. If you do not specify this date first, CDO raises an error.


CdoPostUsing Enum

The CdoPostUsing enumeration is used when setting the http://schemas.microsoft.com/cdo/configuration/postusing field to specify how a message should be posted. Posting can occur through the network using the NNTP protocol, by writing the message to the local NNTP service drop directory, if available, or through a computer running Microsoft® Exchange Server. The postusing field defaults to cdoPostUsingPickup if there is an NNTP service installed on the local computer.

Name | Value | Description
cdoPostUsingPickup | 1 | Post the message using the NNTP service pickup directory.
cdoPostUsingPort | 2 | Post the message using the network. (NNTP protocol over the network).
cdoPostUsingExchange (CDOEX only) | 3 | Post the message using Exchange.

Remarks

If you specify the value cdoPostUsingPort, you will either need the default values provided by the default Outlook Express configuration on the local computer, or you will need to set the fields manually. These fields include:

  • http://schemas.microsoft.com/cdo/configuration/nntpserverport
  • http://schemas.microsoft.com/cdo/configuration/nntpserver

If you specify cdoPostUsingExchange, you specify the following properties in the Configuration object:

Field | Description
http://schemas.microsoft.com/exchange/hardlinklist | The URLs to folders in which to post the message. If this option is set, the Newsgroups property is ignored. Currently, only one URL can be specified in this multivalued property.
http://schemas.microsoft.com/cdo/configuration/activeconnection | An ADO Connection object bound to the user's mailbox private store. If this connection is not specified, a new connection is created to send the message. If the sending object (for example, a Message object) is currently bound to an item, the binding is replaced when the new connection is created. If a Connection object is specified in this property, the current object's binding is not changed, and the object uses this connection to send the message.
http://schemas.microsoft.com/cdo/configuration/mailboxurl | The URL to the user's mailbox base folder.
http://schemas.microsoft.com/cdo/configuration/postusername | The user's principal name (UPN) or URL in the form user@domain.tld or mailto:user@domain.tld. You can also specify the user using the Microsoft Windows NT® 4.0 format, such as DOMAIN\User. If the user's mailbox URL is not specified in the http://schemas.microsoft.com/cdo/configuration/mailboxurl configuration property, Active Directory™ is searched using this UPN.
http://schemas.microsoft.com/cdo/configuration/postpassword | The user's password, used to authenticate with remote servers when sending messages, and to authenticate with Active Directory when searching for user information.

See http://schemas.microsoft.com/cdo/configuration/ namespace fields for more information.


CdoPriorityValues Enum

The CdoPriorityValues enumeration is used to set the Priority property of the IAppointment interface and the urn:schemas:mailheader:priority field.

Name | Value | Description
cdoPriorityNonUrgent | -1 | Nonurgent priority.
cdoPriorityNormal | 0 | Normal priority.
cdoPriorityUrgent | 1 | Urgent priority.


CdoProtocolsAuthentication Enum

The CdoProtocolsAuthentication enumeration is used to set the smtpauthenticate and nntpauthenticate fields in a Configuration object. Using this enumeration, you specify what authentication mechanism (if any) is used to perform authentication with an SMTP or NNTP service when sending or posting messages over the network. Sending or posting messages over the network using TCP/IP and SMTP/NNTP protocols is controlled using the sendusing and postusing fields.

Name | Value | Description
cdoAnonymous | 0 | Perform no authentication.
cdoBasic | 1 | Use the basic (clear text) authentication mechanism.
cdoNTLM | 2 | Use the NTLM authentication mechanism.


CdoReferenceType Enum

The CdoReferenceType enumeration is used when calling the IMessage::AddRelatedBodyPart method. Using the enumeration, you can specify how a related MIME entity, such as an included image, is to be referenced within MHTML formatted messages using a Content-ID header, or a Content-Location header.

Name | Value | Description
cdoRefTypeId | 0 | The Reference parameter contains a value for the Content-ID header.
cdoRefTypeLocation | 1 | The Reference parameter contains a value for the Content-Location header.


CdoResolvedStatus Enum

The CdoResolvedStatus enumeration is used to set the ResolvedStatus property of the IAddressee interface.

Name | Value | Description
cdoUnresolved | 0 | The addressee has not been successfully resolved, meaning that the corresponding directory object has not been identified.
cdoResolved | 1 | The addressee's directory object has successfully been located, and the addressee is considered resolved.
cdoAmbiguous | 2 | A previous attempt to resolve the addressee, that is, locate the corresponding directory object, resulted in multiple matches. The search criteria were ambiguous, and multiple directory objects that match this criteria have been found and are present in the AmbiguousNames recordset.


CdoSendUsing Enum

The CdoSendUsing enumeration is used to set the http://schemas.microsoft.com/cdo/configuration/sendusing field when configuring the Message object. The sendusing field defaults to cdoSendUsingPickup if there is a local SMTP service available on the computer.

Name | Value | Description
cdoSendUsingPickup | 1 | Send message using the local SMTP service pickup directory.
cdoSendUsingPort | 2 | Send the message using the network (SMTP protocol over the network).
cdoSendUsingExchange | 3 | Send the message using the Exchange mail submission URI. This URI is found in the user's urn:schemas:httpmail:sendmsg mailbox folder property.

Remarks

If you specify the value cdoSendUsingPort, you will either need the default values provided by the default Outlook Express configuration on the local machine, or you will need to set the fields manually. These fields include:

  • http://schemas.microsoft.com/cdo/configuration/smtpserverport
  • http://schemas.microsoft.com/cdo/configuration/smtpserver

If you specify cdoSendUsingExchange, you specify the following properties in the Configuration object:

Field | Description
http://schemas.microsoft.com/cdo/configuration/mailboxurl | The URL to the user's mailbox. If this property is not set, the mailbox URL is constructed by searching Active Directory for the user specified in the sendusername property and finding the user's Exchange server.
http://schemas.microsoft.com/cdo/configuration/activeconnection | An ADO Connection object bound to the user's mailbox private store. If this connection is not specified, a new connection is created to send the message. If the sending object (for example, a Message object) is currently bound to an item, the binding is replaced when the new connection is created. If a Connection object is specified in this property, the current object's binding is not changed, and the object uses this connection to send the message.
http://schemas.microsoft.com/cdo/configuration/sendusername | The user's principal name (UPN) or URL in the form user@domain.tld or mailto:user@domain.tld. You can also specify the user using the Microsoft Windows NT 4.0 format, such as DOMAIN\User. If the user's mailbox URL is not specified in the mailboxurl configuration property, Active Directory is searched using this UPN.
http://schemas.microsoft.com/cdo/configuration/sendpassword | The user's password, used to authenticate with remote servers when sending messages, and to authenticate with Active Directory when searching for user information.

See http://schemas.microsoft.com/cdo/configuration/ namespace fields for more information.


CdoSensitivityValues Enum

The CdoSensitivityValues enumeration is used to set the Sensitivity property of the IAppointment interface and the urn:schemas:mailheader:sensitivity field.

Name | Value | Description
cdoSensitivityNone | 0 | None.
cdoPersonal | 1 | Personal.
cdoPrivate | 2 | Private.
cdoCompanyConfidential | 3 | Company Confidential


CdoTimeZoneId Enum

The CdoTimeZoneId enumeration identifies the client's time zone used to display appointment times. All appointments are stored in the Microsoft® Web Storage System in (coordinated universal time or Greenwich Mean Time) UTC and are converted by the client program to the appropriate time zone. If a valid time zone is specified, CDO converts appointments to the correct local time.

Name | Value | Description
cdoUTC | 0 | Coordinated Universal Time (UTC)
cdoGMT | 1 | Greenwich Mean Time (same as UTC)
cdoLisbon | 2 | Dublin, Edinburgh, Lisbon, London (UTC + 0:00)
cdoParis | 3 | Brussels, Copenhagen, Madrid, Paris, Vilnius (UTC + 1:00)
cdoBerlin | 4 | Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna (UTC + 1:00)
cdoEasternEurope | 5 | Eastern Europe (UTC + 2:00)
cdoPrague | 6 | Belgrade, Bratislava, Budapest, Ljubljana, Prague (UTC + 1:00)
cdoAthens | 7 | Athens, Instanbul, Minsk (UTC + 2:00)
cdoBrasilia | 8 | Brasilia (UTC - 3:00)
cdoAtlanticCanada | 9 | Atlantic time (UTC - 4:00)
cdoEastern | 10 | Eastern time (UTC - 5:00)
cdoCentral | 11 | Central time (UTC - 6:00)
cdoMountain | 12 | Mountain time (UTC - 7:00)
cdoPacific | 13 | Pacific time (UTC - 8:00)
cdoAlaska | 14 | Alaska (UTC - 9:00)
cdoHawaii | 15 | Hawaii (UTC - 10:00)
cdoMidwayIsland | 16 | Midway Island, Samoa (UTC - 11:00)
cdoWellington | 17 | Auckland, Wellington (UTC + 12:00)
cdoBrisbane | 18 | Brisbane (UTC + 10:00)
cdoAdelaide | 19 | Adelaide (UTC + 9:30)
cdoTokyo | 20 | Osaka, Sapporo, Tokyo (UTC + 9:00)
cdoHongKong | 21 | Hong Kong SAR(UTC + 8:00)
cdoBangkok | 22 | Bangkok, Hanoi, Jakarta (UTC + 7:00)
cdoBombay | 23 | Bombay, Calcutta, Madras, New Delhi (UTC + 5:30)
cdoAbuDhabi | 24 | Abu Dhabi, Muscat (UTC + 4:00)
cdoTehran | 25 | Tehran (UTC + 3:30)
cdoBaghdad | 26 | Baghdad, Kuwait, Riyadh (UTC + 3:00)
cdoIsrael | 27 | Israel (UTC + 2:00)
cdoNewfoundland | 28 | Newfoundland (UTC - 3:30)
cdoAzores | 29 | Azores, Cape Verde Islands (UTC - 1:00)
cdoMidAtlantic | 30 | Mid Atlantic (UTC - 2:00)
cdoMonrovia | 31 | Casablanca, Monrovia (UTC + 0:00)
cdoBuenosAires | 32 | Buenos Aires, Georgetown (UTC - 3:00)
cdoCaracas | 33 | Caracas, La Paz (UTC - 4:00)
cdoIndiana | 34 | Indiana (UTC - 5:00)
cdoBogota | 35 | Bogota, Lima, Quito (UTC - 5:00)
cdoSaskatchewan | 36 | Saskatchewan (UTC - 6:00)
cdoMexicoCity | 37 | Mexico City, Tegucigalpa (UTC - 6:00)
cdoArizona | 38 | Arizona (UTC - 7:00)
cdoEniwetok | 39 | Eniwetok, Kwajalein (UTC - 12:00)
cdoFiji | 40 | Fiji Islands, Kamchatka, Marshall Islands (UTC + 12:00)
cdoMagadan | 41 | Magadan, Solomon Islands, New Caledonia (UTC + 11:00)
cdoHobart | 42 | Hobart (UTC + 10:00)
cdoGuam | 43 | Guam, Port Moresby (UTC + 10:00)
cdoDarwin | 44 | Darwin (UTC + 9:30)
cdoBeijing | 45 | Beijing, Chongqing, Urumqi, (UTC + 8:00)
cdoAlmaty | 46 | Akmola, Almaty, Dhaka (UTC + 6:00)
cdoIslamabad | 47 | Islamabad, Karachi, Tashkent (UTC + 5:00)
cdoKabul | 48 | Kabul (UTC + 4:30)
cdoCairo | 49 | Cairo (UTC + 2:00)
cdoHarare | 50 | Harare, Pretoria (UTC + 2:00)
cdoMoscow | 51 | Moscow, St. Petersburg, Volgograd (UTC + 3:00)
cdoInvalidTimeZone | 52 | Invalid time zone


CdoWfAdhocFlows Enum

The CdoWfAdhocFlows enumeration manages process definition policy for a workflow folder. You set "http://schemas.microsoft.com/cdo/workflow/adhocflows" as a property of the OnSyncSave event registration item. The property can have one of the following three values:

Name | Value | Description
PreventAdhocFlows | 0 | Only the default process definition applies to each process instance in the workflow folder.
PermitAdhocFlows | 1 | Each process instance can use its own process definition. Default is still used if a process instance declares no process definition.
OnlyAdhocFlows | 2 | Each process instance must declare its own process definition.


CdoWfMemberType Enum

The CdoWfMemberType enumeration identifies the type of name returned by the IMember interface Name property.

Name | Value | Description
cdowfEmailAddress | 0 | Name is an e-mail address. Example: "someone@microsoft.com"
cdowfRole | 1 | Name is a folder role. Folder roles are created and populated programmatically. The only valid names are: "Role1", "Role2", ... "Role16".

See Also

IMember Interface

© 2000-2001 Microsoft Corporation. All rights reserved.


CdoUserIDType Enum

The CdoUserIDType enumeration identifies the type of name passed in the first parameter of the IWorkflowSession interface, GetUserProperty method.

Name | Value | Description
cdowfUserEmailAddress | 0 | Parameter is an e-mail address in the form "someone@microsoft.com".
cdowfDistinguishedName | 1 | Parameter is a distinguished name in Active Directory.


CdoWfAuditTrailEvents Enum

CdoWfAuditTrailEvents enumeration identifies an audit trail entry type used by the workflow engine.

Name | Value | Description
cdowfATECustom | 0 | Entry made by workflow script.
CdowfATEStateChange | 1 | Entry made on state change.
CdowfATECompAction | 2 | Entry made after OnAbort workflow event.
CdowfATESecurity | 3 | Entry made because of security or configuration problems with the workflow item.

See Also

IAuditTrail

IAuditTrail.AddEntry

AuditTrailEventLog

© 2000-2001 Microsoft Corporation. All rights reserved.


CdoWfEventType Enum

The CdoWfEventType enumeration is set by the workflow event sink before it calls the workflow engine. The event sink calls ProcessInstance.Advance with this as its first argument.

Name | Value | Description
cdowfOnCreate | 1 | Document was created.
cdowfOnChange | 2 | Document was modified.
cdowfOnDelete | 3 | Document was deleted.
cdowfOnExpiry | 4 | Document has been in the current state too long.
cdowfOnReceive | 5 | Received an e-mail response correlating to the document.

See Also

IProcessInstance.Advance

IProcessInstance

© 2000-2001 Microsoft Corporation. All rights reserved.


CdoWfMode Enum

IProcessDefinition.Mode takes this type to designate security privileges for a workflow process. Restricted mode cannot create objects in script actions or conditions. Privileged mode can create any object including custom COM objects in its actions and conditions.

Name | Value | Description
cdowfRestrictedMode | 0x01 | No object-creation privileges.
cdowfPrivilegedMode | 0x02 | Unlimited object-creation privileges.

See Also

IProcessDefinition

IProcessDefinition.Mode

© 2000-2001 Microsoft Corporation. All rights reserved.


CdoWfSendFlags Enum

The CdoWfSentFlags enumeration provides the input parameter for the IWorkflowMessage,SendWorkflowMessage method.

Name | Value | Description
cdowfNoTracking | 0x00 | Turns off response tracking.
cdowfAdd | 0x01 | Indicates that responses from anyone may be added to the TrackingTable. Allows tracking responses from a Distribution List or delegate.
cdowfStrict | 0x02 | Indicates that only responses from original recipient may be added to the TrackingTable. Does not allow tracking of responses from a Distribution List or delegate.


CdoWfTransitionFlags Enum

The CdoWfTransitionFlags enumeration is used in the Flags field of the action table to specify what combination of objects and scripts are used for the conditions and actions in that action table row. Binary values are joined by a logical OR to create the flag. The workflow engine assumes that all actions and conditions are scripts; therefore a value of zero (0x00) indicates no custom (COM) actions or conditions.

Name | Value | Description
cdowfActnObject | 0x01 | Action is an object.
cdowfCondObject | 0x02 | Condition is an object.
cdowfCompObject | 0x04 | CompensatingAction is an object.
cdowfEndState | 0x08 | The state being entered is considered the last state of the workflow.

See Also

IProcessDefinition

IProcessDefinition.ActionTable

Conditions and Actions

© 2000-2001 Microsoft Corporation. All rights reserved.


Schema Properties

The following sections define the properties that are obtained from CDO Fields collections.

http://schemas.microsoft.com/cdo/configuration/ Namespace

http://schemas.microsoft.com/cdo/nntpenvelope/ Namespace

http://schemas.microsoft.com/cdo/smtpenvelope/ Namespace

http://schemas.microsoft.com/cdo/workflow/ Namespace

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


http://schemas.microsoft.com/cdo/configuration/ Namespace

Platform SDK: Exchange 2000 Server

http://schemas.microsoft.com/cdo/
configuration/ Namespace

The http://schemas.microsoft.com/cdo/configuration/ namespace defines the majority of fields used to set configurations for various CDO objects. These configuration fields are set using an implementation of the IConfiguration.Fields collection.

Many CDO objects use information stored in an associated Configuration object to define configuration settings. One example is the Message object, where you use its associated Configuration object to set fields such as sendusing. This field defines whether to send the message using the local SMTP service drop directory (if the local machine has the SMTP service installed), using an SMTP service directly over the network, or using Exchange. If sending over the network, you set smtpservername to specify the IP address or Domain Name System (DNS) name of the machine hosting the SMTP service, and optionally, smtpserverport to specify a port value. If credentials are required for connecting to an SMTP service, you can specify them by setting sendusername and sendpassword.

A similar set of fields exists for posting messages either using a local NNTP service pickup directory or over the network.

All of the names listed in the following topics are also defined as string constants in the type library and .idl file for convenience.

Named Constant

cdoNSDAV


activeconnection Field

The ActiveConnection object to use when sending messages through Microsoft® Exchange 2000 Server.

Full Name

http://schemas.microsoft.com/cdo/configuration/activeconnection

Named Constant

cdoActiveConnection

OLE DB Type

DBTYPE_WSTR

Remarks

This ActiveConnection object reference is only used when sending messages using Exchange. To send messages using Exchange, set the http://schemas.microsoft.com/cdo/configuration/sendusing configuration field (CdoSendUsingMethod) to the value cdoSendUsingExchange (3). The ADO Connection object must be currently bound to the user's private mailbox store.

No transaction is assumed for this Connection object when sending a message. To send messages within a transaction when using a provider that supports transactions, first call _Connection.BeginTrans on this Connection object, send the message using the IMessage.Send method, then either commit or abort the transaction using the _Connection.CommitTrans or _Connection.RollbackTrans method respectively.

See Also

IMessage.Send

http://schemas.microsoft.com/cdo/configuration/sendusing

CdoSendUsing

© 2000-2001 Microsoft Corporation. All rights reserved.


autopromotebodyparts Field

Specifies whether multipart body parts that contain a single child body part are replaced with the child when the MIME stream is constructed.

Full Name

http://schemas.microsoft.com/cdo/configuration/autopromotebodyparts

Named Constant

cdoAutoPromoteBodyParts

OLE DB Type

DBTYPE_BOOL

Remarks

The multipart body part content type is designed to relate two or more child body parts. When a body part that is marked multipart contains only one child, this flag determines whether the child is automatically promoted to the parent's position when the message and the stream are constructed.

The default for this property is True (VARIANT_TRUE).

Example

True (VARIANT_TRUE)


flushbuffersonwrite Field

A boolean flag indicating whether file system buffers are to be flushed when messages are written to the SMTP and NNTP pickup directories.

Full Name

http://schemas.microsoft.com/cdo/configuration/flushbuffersonwrite

Named Constant

cdoFlushBuffersOnWrite

OLE DB Type

DBTYPE_BOOL

Remarks

This field can be used both for SMTP and NNTP configurations. If the current configuration specifies using the pickup directories for the SMTP and NNTP services when sending or posting messages, setting this value to True (VARIANT_TRUE) forces the writing of the message file directly to disk, overriding file system buffering.

Example

True (VARIANT_TRUE)


httpcookies Field

Cookies sent along with HTTP requests for HTML pages through the IMessage.CreateMHTMLBody and IMessage.AddAttachment methods.

Full Name

http://schemas.microsoft.com/cdo/configuration/httpcookies

Named Constant

cdoHTTPCookies

OLE DB Type

DBTYPE_WSTR

Example

CookieName1=CookieVal1;CookieName2=CookieVal2

See Also

IMessage.AddAttachment

IMessage.CreateMHTMLBody

© 2000-2001 Microsoft Corporation. All rights reserved.


languagecode Field

The language code used to localize message response text that is inserted when replying or forwarding messages.

Full Name

http://schemas.microsoft.com/cdo/configuration/languagecode

Named Constant

cdoLanguageCode

OLE DB Type

DBTYPE_WSTR

Remarks

Response text is only generated if the http://schemas.microsoft.com/cdo/configuration/usemessageresponsetext field is set to True.

Language codes are defined in Request for Comments (RFC) 1766 and are used to identify the LCID value for a particular locale.

Example

de


mailboxurl Field

The URL to a user's mailbox folder.

Full Name

http://schemas.microsoft.com/cdo/configuration/mailboxurl

Named Constant

cdoMailboxURL

OLE DB Type

DBTYPE_WSTR

Remarks

When sending or posting messages using Exchange, CDO uses the user's mail submission URI. In order to do so, it must bind to the user's root mailbox folder and determine the submission URI through the urn:schemas:httpmail:sendmsg property. If you set the mailboxurl property, this URL is used to bind to the user's mailbox. If not, CDO uses the user principal name specified by sendusername or postusername (http://schemas.microsoft.com/cdo/configuration namespace) to look up the user's Exchange server in Active Directory™. Setting the mailboxurl property explicitly increases performance.

Note The mailbox folder for a user is not the inbox. For example, http://server/exchange/user1 is User1's mailbox folder, and the URL to the user's inbox is found by requesting the urn:schemas:httpmail:inbox property for the root mailbox folder item.


nntpaccountname Field

The Microsoft® Outlook® Express (OE) NNTP account name available for information purposes only.

Full Name

http://schemas.microsoft.com/cdo/configuration/nntpaccountname

Named Constant

cdoNNTPAccountName

OLE DB Type

DBTYPE_WSTR

(Read-only)

Remarks

This field is populated when the Outlook Express configuration settings are loaded.

Example

MyAccount

© 2000-2001 Microsoft Corporation. All rights reserved.


nntpauthenticate Field

The authentication mechanism to use when authenticating to an NNTP service over the network.

Full Name

http://schemas.microsoft.com/cdo/configuration/nntpauthenticate

Named Constant

cdoNNTPAuthenticate

OLE DB Type

DBTYPE_I4

Remarks

This field is relevant only if the http://schemas.microsoft.com/cdo/configuration/postusing field is set to cdoPostUsingPort.

Use the CdoProtocolsAuthentication enumeration to set the value of this field. If this field is not set, no authentication is attempted when posting messages using the NNTP protocol.

Example

cdoNTLM


nntpconnectiontimeout Field

The number of seconds that can elapse without a response from the NNTP service before the connection attempt is aborted.

Full Name

http://schemas.microsoft.com/cdo/configuration/nntpconnectiontimeout

Named Constant

cdoNNTPConnectionTimeout

OLE DB Type

DBTYPE_I4

Remarks

The default value for this field is 30 seconds. If Outlook Express is installed, then the value from the default account is used.

Example

40


nntpserver Field

The DNS or NetBios name of the host to which to post messages using the NNTP protocol.

Full Name

http://schemas.microsoft.com/cdo/configuration/nntpserver

Named Constant

cdoNNTPServer

OLE DB Type

DBTYPE_WSTR

Remarks

This field is only relevant if the http://schemas.microsoft.com/cdo/configuration/postusing field is set to cdoPostUsingPort (2). If Outlook Express is installed, then the value from the default account is used.

Example

news.microsoft.com


nntpserverpickupdirectory Field

The full path to the NNTP service pickup directory.

Full Name

http://schemas.microsoft.com/cdo/configuration/nntpserverpickupdirectory

Named Constant

cdoNNTPServerPickupDirectory

OLE DB Type

DBTYPE_WSTR

Remarks

This field is only relevant if the http://schemas.microsoft.com/cdo/configuration/postusing field is set to cdoPostUsingPickup (1).

Example

c:\Inetpub\nntproot\pickup


nntpserverport Field

The port on which the NNTP service is listening for connections.

Full Name

http://schemas.microsoft.com/cdo/configuration/nntpserverport

Named Constant

cdoNNTPServerPort

OLE DB Type

DBTYPE_I4

Remarks

This field is only relevant if the http://schemas.microsoft.com/cdo/configuration/postusing field is set to cdoPostUsingPort (2). The default is 119.

Example

119


nntpusessl Field

A boolean value indicating whether the Secure Sockets Layer (SSL) should be used when posting messages over the network using the NNTP protocol.

Full Name

http://schemas.microsoft.com/cdo/configuration/nntpusessl

Named Constant

cdoNNTPUseSSL

OLE DB Type

DBTYPE_BOOL

Remarks

This field is only relevant if the http://schemas.microsoft.com/cdo/configuration/postusing field is set to cdoPostUsingPort (2). If Outlook Express is installed, then the value from the default account is used.

Example

True (VARIANT_TRUE)


postemailaddress Field

The user's e-mail address used when posting messages.

Full Name

http://schemas.microsoft.com/cdo/configuration/postemailaddress

Named Constant

cdoPostEmailAddress

OLE DB Type

DBTYPE_WSTR

Remarks

If Outlook Express is installed, then the value from the default account is used.

Example

myname@microsoft.com


postpassword Field

The password used in conjunction with postusername when authenticating over the network.

Full Name

http://schemas.microsoft.com/cdo/configuration/postpassword

Named Constant

cdoPostPassword

OLE DB Type

DBTYPE_WSTR

Remarks

This field is only relevant if the http://schemas.microsoft.com/cdo/configuration/postusing field is set to cdoPostUsingPort (2) or cdoPostUsingExchange. If Outlook Express is installed, then the value from the default account is used.

When posting a message using Exchange, this password is used in conjunction with the user principal name in the postusername field to authenticate remotely over HTTP.

Example

password


postusername Field

The username used in conjunction with postpassword when authenticating with an NNTP service over the network. The user principal name used to authenticate when posting messages remotely using Exchange.

Full Name

http://schemas.microsoft.com/cdo/configuration/postusername

Named Constant

cdoPostUserName

OLE DB Type

DBTYPE_WSTR

Remarks

This field is only relevant if the http://schemas.microsoft.com/cdo/configuration/postusing field is set to cdoPostUsingPort (2) or cdoPostUsingExchange. If Outlook Express is installed, then the value from the default account is used.

When posting a message using Exchange, this value is the user's UPN (user principal name). If the http://schemas.microsoft.com/cdo/configuration/mailboxurl property is not set, CDO uses this UPN to look up the Exchange server hosting the user's mailbox. When authenticating with Active Directory, the UPN and postpassword value are used for credentials.

Example

Microsoft Windows NT® 4.0 compatible format:

domain\username

User principal name format:

user12@domain.higherdomain.tld


postuserreplyemailaddress Field

The reply e-mail address for the message.

Full Name

http://schemas.microsoft.com/cdo/configuration/postuserreplyemailaddress

Named Constant

cdoPostUserReplyEmailAddress

OLE DB Type

DBTYPE_WSTR

Remarks

If Outlook Express is installed, then the value from the default account is used.

Example

user@microsoft.com


postusing Field

The mechanism to use to post messages.

Full Name

http://schemas.microsoft.com/cdo/configuration/postusing

Named Constant

cdoPostUsingMethod

OLE DB Type

DBTYPE_I4

Remarks

Use the CdoPostUsing enumeration to set this value. If the NNTP service is installed, then the value defaults to cdoPostUsingPickup. Otherwise, if Outlook Express is installed, the value defaults to cdoPostUsingPort and the settings from the default account are used.

Example

cdoPostUsingPickup (1)

cdoPostUsingPort (2)

cdoPostUsingExchange (3)


savesentitems Field

Indicates whether messages are to be saved in a user's Sent Items folder when messages are sent through Microsoft® Exchange 2000 Server using the Microsoft® Web Storage System OLE DB provider or the WebDAV protocol.

Full Name

http://schemas.microsoft.com/cdo/configuration/savesentitems

Named Constant

cdoSaveSentItems

OLE DB Type

DBTYPE_BOOL

Remarks

This field has no effect when you send messages using the SMTP service pickup directory or over the network using the Simple Mail Transfer Protocol (SMTP). The default value for this field is True (VARIANT_TRUE).

Example

True

See Also

http://schemas.microsoft.com/cdo/configuration/sendusing

CdoSendUsing

© 2000-2001 Microsoft Corporation. All rights reserved.


sendemailaddress Field

The default e-mail address of the message sender.

Full Name

http://schemas.microsoft.com/cdo/configuration/sendemailaddress

Named Constant

cdoSendEmailAddress

OLE DB Type

DBTYPE_WSTR

Remarks

If Outlook Express is installed, then the value from the default account is used.

Example

myname@microsoft.com


sendpassword Field

The password used in conjunction with the sendusername field when authenticating to an SMTP or Exchange WebDAV service over the network.

Full Name

http://schemas.microsoft.com/cdo/configuration/sendpassword

Named Constant

cdoSendPassword

OLE DB Type

DBTYPE_WSTR

(Write-Only)

Remarks

This field is only relevant if the http://schemas.microsoft.com/cdo/configuration/sendusing field is set to cdoSendUsingPort (2) or cdoSendUsingExchange. If Outlook Express is installed, then the value from the default account is used.

When sending using Exchange, this password is used with the user principal name (UPN) specified in the sendusername field to authenticate with Active Directory and remote Exchange HTTP services.

Example

password


sendusername Field

The username used in conjunction with the sendpassword field when authenticating to an SMTP or Exchange HTTP service over the network.

Full Name

http://schemas.microsoft.com/cdo/configuration/sendusername

Named Constant

cdoSendUserName

OLE DB Type

DBTYPE_WSTR

Remarks

This field is only relevant if the http://schemas.microsoft.com/cdo/configuration/sendusing field is set to cdoSendUsingPort (2) or cdoSendUsingExchange. If Outlook Express is installed, then the value from the default account is used.

When sending messages using Exchange, this value should be the user's user principal name (UPN). This value along with the password in the sendpassword field is used to authenticate with Active Directory and remote Exchange 2000 WebDAV services. If the http://schemas.microsoft.com/cdo/configuration/mailboxurl is not set in the Configuration object, CDO uses this UPN to find the Exchange server on which this user's mailbox resides.

Example

Microsoft Windows NT 4.0 compatible format:

domain\username

User principal name format:

user12@domain.tld


senduserreplyemailaddress Field

The reply e-mail address for the message when sending messages using an SMTP service.

Full Name

http://schemas.microsoft.com/cdo/configuration/senduserreplyemailaddress

Named Constant

cdoSendUserReplyEmailAddress

OLE DB Type

DBTYPE_WSTR

Remarks

If Outlook Express is installed, then the value from the default account is used.

Example

user@microsoft.com


sendusing Field

The mechanism to use to send messages.

Full Name

http://schemas.microsoft.com/cdo/configuration/sendusing

Named Constant

cdoSendUsingMethod

OLE DB Type

DBTYPE_I4

Remarks

Use the CdoSendUsing enumeration to set this value. If the SMTP service is installed on the local machine, then the value defaults to cdoSendUsingPickup (1). Otherwise, if Outlook Express is installed, the value defaults to cdoSendUsingPort (2) and the settings from the default account are used.

Example

cdoSendUsingPickup

cdoSendUsingPort

cdoSendUsingExchange


smtpaccountname Field

The Microsoft® Outlook® Express (OE) SMTP account name available for information purposes only.

Full Name

http://schemas.microsoft.com/cdo/configuration/smtpaccountname

Named Constant

cdoSMTPAccountName

OLE DB Type

DBTYPE_WSTR

Remarks

This field is populated when the Outlook Express configuration settings are loaded.

Example

MyAccount

© 2000-2001 Microsoft Corporation. All rights reserved.


smtpauthenticate Field

The authentication mechanism to use when authenticating to an SMTP service over the network.

Full Name

http://schemas.microsoft.com/cdo/configuration/smtpauthenticate

Named Constant

cdoSMTPAuthenticate

OLE DB Type

DBTYPE_I4

Remarks

This field is relevant only if the http://schemas.microsoft.com/cdo/configuration/sendusing field is set to cdoSendUsingPort.

Use the CdoProtocolsAuthentication enumeration to set the value of this field. If this field is not set, no authentication is attempted when posting messages using the SMTP protocol.

Example

cdoNTLM


smtpconnectiontimeout Field

The number of seconds that can elapse without a response from the SMTP service before the connection attempt is aborted.

Full Name

http://schemas.microsoft.com/cdo/configuration/smtpconnectiontimeout

Named Constant

cdoSMTPConnectionTimeout

OLE DB Type

DBTYPE_I4

Remarks

The default value for this field is 30 seconds. If Outlook Express is installed, then the value from the default account is used.

Example

40


smtpserver Field

The DNS or NetBios name of the host to which to post messages using the SMTP protocol.

Full Name

http://schemas.microsoft.com/cdo/configuration/smtpserver

Named Constant

cdoSMTPServer

OLE DB Type

DBTYPE_WSTR

Remarks

This field is only relevant if the http://schemas.microsoft.com/cdo/configuration/sendusing field is set to cdoSendUsingPort (2). If Outlook Express is installed, then the value from the default account is used.

Example

mail.microsoft.com


smtpserverpickupdirectory Field

The full path to the local SMTP service pickup directory.

Full Name

http://schemas.microsoft.com/cdo/configuration/smtpserverpickupdirectory

Named Constant

cdoSMTPServerPickupDirectory

OLE DB Type

DBTYPE_WSTR

Remarks

This field is only relevant if the http://schemas.microsoft.com/cdo/configuration/sendusing field is set to cdoSendUsingPickup (1).

Example

c:\Inetpub\mailroot\pickup


smtpserverport Field

The port on which the SMTP service is listening.

Full Name

http://schemas.microsoft.com/cdo/configuration/smtpserverport

Named Constant

cdoSMTPServerPort

OLE DB Type

DBTYPE_I4

Remarks

This field is only relevant if the http://schemas.microsoft.com/cdo/configuration/sendusing field is set to cdoSendUsingPort (2). The default is 25.

Example

25


smtpusessl Field

A boolean value indicating whether the Secure Sockets Layer (SSL) should be used when posting messages over the network using the SMTP protocol.

Full Name

http://schemas.microsoft.com/cdo/configuration/smtpusessl

Named Constant

cdoSMTPUseSSL

OLE DB Type

DBTYPE_BOOL

Remarks

This field is only relevant if the http://schemas.microsoft.com/cdo/configuration/sendusing field is set to cdoSendUsingPort (2). If Outlook Express is installed, then the value from the default account is used.

Example

True (VARIANT_TRUE)


urlgetlatestversion Field

A boolean value indicating whether any locally cached Web pages should be bypassed and the latest version of a resource retrieved over HTTP.

Full Name

http://schemas.microsoft.com/cdo/configuration/urlgetlatestversion

Named Constant

cdoURLGetLatestVersion

OLE DB Type

DBTYPE_BOOL

Example

True (VARIANT_TRUE)


urlproxybypass Field

The string <local> indicates that the proxy server set in the http://schemas.microsoft.com/cdo/configuration/urlproxyserver is to be bypassed for local addresses.

Full Name

http://schemas.microsoft.com/cdo/configuration/urlproxybypass

Named Constant

cdoURLProxyBypass

OLE DB Type

DBTYPE_WSTR

Remarks

This string must only be set to <local>. Setting it to other values will not cause a run-time exception, but the proxy service will not be bypassed.

Example

<local>

© 2000-2001 Microsoft Corporation. All rights reserved.


urlproxyserver Field

The DNS or NetBios name and port number of the proxy service to use when retrieving resources over the network.

Full Name

http://schemas.microsoft.com/cdo/configuration/urlproxyserver

Named Constant

cdoURLProxyServer

OLE DB Type

DBTYPE_WSTR

Remarks

The proxy settings affect the entire process, not just the current thread. You cannot use different settings for different threads in the same process.

Both the DNS/NetBios name and the port value are required in the format name:port.

Example

proxyserver:80


urlsource Field

Indicates the location of the mailbox to use when sending or posting messages. Default is 0 (cdoExchangeServerURL).

Full Name

http://schemas.microsoft.com/cdo/configuration/urlsource

Named Constant

cdoURLSource

OLE DB Type

DBTYPE_I4

Remarks

Currently, only the value cdoExchangeServerURL (0) is supported. CDO identifies the Exchange Server computer on which a user's mailbox resides by first looking at the http://schemas.microsoft.com/cdo/configuration/mailboxurl property. If this property is empty, the mailbox URL is looked up in Active Directory using the user principal name (UPN) specified in the http://schemas.microsoft.com/cdo/configuration/sendusername or http://schemas.microsoft.com/cdo/configuration/postusername field.


usemessageresponsetext Field

A boolean value indicating whether response text is inserted when replying to or forwarding messages.

Full Name

http://schemas.microsoft.com/cdo/configuration/usemessageresponsetext

Named Constant

cdoUseMessageResponseText

OLE DB Type

DBTYPE_BOOL

Remarks

The default value is True.

Message response text is localized into the language identified by the http://schemas.microsoft.com/cdo/configuration/languagecode field value.

Example

True (VARIANT_TRUE)


http://schemas.microsoft.com/cdo/nntpenvelope/ Namespace

The http://schemas.microsoft.com/cdo/nntpenvelope/ namespace defines scope for a set of fields that are accessible in the IMessage.EnvelopeFields property of a Message object when it is passed to a transport event sink handling one of the NNTP OnPost, NNTP OnPostEarly, or NNTP OnPostFinal transport events. These fields are only available for messages that are still in transport, and are therefore only used when writing a transport event sink. For more information, see SMTP/NNTP Transport Event Sinks with CDO.


newsgrouplist Field

The newsgroups to which the message is to be posted.

Full Name

http://schemas.microsoft.com/cdo/nntpenvelope/newsgrouplist

OLE DB Type

DBTYPE_WSTR

(Read-only)

Remarks

This field returns a comma-delimited list of newsgroups. The message stored may be different then what is in the Newsgroups header.

This is read-only during the NNTP OnPostFinal event.

See Also

IMessage.EnvelopeFields

SMTP/NNTP Transport Event Sinks with CDO

© 2000-2001 Microsoft Corporation. All rights reserved.


nntpprocessing Field

A bit-mask used to specify what NNTP processing should occur for a message.

Full Name

http://schemas.microsoft.com/cdo/nntpenvelope/nntpprocessing

OLE DB Type

DBTYPE_I4

Remarks

This field is a bit-mask used to specify how the posted NNTP message is to be handled. The value ranges from 0 to 7 (4 & 2 & 1 & 0). These bits can be set using the following enumeration constants:

Name | Value | Description
cdoPostMessage | 1 | The message will be posted.
cdoProcessControl | 2 | The message will be send through process control.
cdoProcessModerator | 4 | The message will be sent through the moderator.

All even values for this process (in other words, without the cdoPostMessage bit set) are blocked from being posted, and neither process controls nor process moderators are run for the message. The values are:

  • even or zero - block posting; no process control; no process moderator.
  • 1 - post message; no process control; no process moderator.
  • 3 - post message and run process control.
  • 5 - post message and run process moderator.
  • 7 - post message; run process control; run process moderator.

This is not available during the NNTP OnPostFinal event.

See Also

IMessage.EnvelopeFields

SMTP/NNTP Transport Event Sinks with CDO

© 2000-2001 Microsoft Corporation. All rights reserved.


http://schemas.microsoft.com/cdo/smtpenvelope/ Namespace

The http://schemas.microsoft.com/cdo/smtpenvelope/ namespace defines a scope for message transport envelope fields. These fields are only available for messages passed to SMTP OnArrival transport event sinks implemented using CDO. These fields are contained in the object's IMessage.EnvelopeFields collection.

See Also

SMTP/NNTP Transport Event Sinks with CDO

© 2000-2001 Microsoft Corporation. All rights reserved.


arrivaltime Field

The date and time the message arrived.

Full Name

http://schemas.microsoft.com/cdo/smtpenvelope/arrivaltime

OLE DB Type

DBTYPE_DATE

(Read-only)

Remarks

The date and time are returned in Coordinated Universal Time (UTC).

Example

10/4/1999 11:30 AM

© 2000-2001 Microsoft Corporation. All rights reserved.


clientipaddress Field

The IP address of the client that submitted the message to the SMTP service.

Full Name

http://schemas.microsoft.com/cdo/smtpenvelope/clientipaddress

OLE DB Type

DBTYPE_WSTR

(Read-only)

Remarks

The address is a string listed in the standard "dot-quad" notation.

Example

127.0.0.1


messagestatus Field

The transport status of the message.

Full Name

http://schemas.microsoft.com/cdo/smtpenvelope/messagestatus

OLE DB Type

DBTYPE_I4

Remarks

The message status can have one of three values defined by the CdoMessageStat enumeration:

Name | Value | Description
cdoStatusSuccess | 0 | Deliver message.
cdoStatusAbortDelivery | 2 | Do not deliver message.
cdoStatusBadMail | 3 | Send message to the bad mail location.

Event sinks can modify these values when executing to change the message's status.

Example

cdoAbortDeliver (2)


pickupfilename Field

The file name that housed the submitted message in the SMTP service pickup directory.

Full Name

http://schemas.microsoft.com/cdo/smtpenvelope/pickupfilename

OLE DB Type

DBTYPE_WSTR

(Read-only)

Remarks

This field is relevant only if the message was submitted to the SMTP service through the local pickup directory. It is empty if the message was submitted through the SMTP protocol over the network.

Example

55452434GUID.eml

© 2000-2001 Microsoft Corporation. All rights reserved.


recipientlist Field

The list of recipients for the message.

Full Name

http://schemas.microsoft.com/cdo/smtpenvelope/recipientlist

OLE DB Type

DBTYPE_WSTR

Remarks

The address list corresponds to the set of RCPT TO SMTP protocol commands received for the message, or the X-receiver headers present at the beginning of the message if it was submitted to the local SMTP service pickup directory.

Each address is in the form submitted by the client. No alteration or expansion of the address has been performed. Each address in the list is delimited by the prefix "SMTP:" and the suffix ";".

Example

SMTP:someone@microsoft.com;SMTP:another@microsoft.com;


senderemailaddress Field

The e-mail address of the message submitter.

Full Name

http://schemas.microsoft.com/cdo/smtpenvelope/senderemailaddress

OLE DB Type

DBTYPE_WSTR

(Read-only)

Remarks

This field corresponds to either the value of the MAIL FROM SMTP protocol command received from the client if submitted over the network or the value of the X-submitter header field present at the beginning of the message file if submitted to the local SMTP service pickup directory.

Example

someone@microsoft.com


http://schemas.microsoft.com/cdo/workflow/ Namespace

The http://schemas.microsoft.com/cdo/workflow namespace contains the Web Storage System schema names for Collaboration Data Objects Workflow (CDOWF) functionality. The CDOWF schema are accessible through Microsoft® ActiveX® Data Objects, OLEDB, and WebDAV. Most of these properties are promoted to the CDOWF objects and are accessible through the CDOWF object model.


actiontable Field

String property containing Extensible Markup Language (XML)-encoded Action Table recordset. The XML RecordSet encoding must be done using the Microsoft Extensible Markup Language MSXML ADO provider.

This property corresponds directly to the ActionTable property on the IProcessInstance interface, in the CDOWF type library. Applications running directly on the server find it simpler to use this CDOWF interface, rather than manipulating the property directly. Applications that access the server remotely need to directly update the store property.

Full Name

http://schemas.microsoft.com/cdo/workflow/actiontable

Name Constant

cdowfActionTableXML

OLE DB Type

DBTYPE_WSTR

© 2000-2001 Microsoft Corporation. All rights reserved.


adhocflows Field

Flag on an application or folder that indicates the following:

Value | Description
0 (default) | Don't allow ad hoc workflows (default)
1 | Permit ad hoc workflows
2 | Allow only ad hoc workflows.

The workflow engine looks for this property in the OnsyncSave registration item for the folder.

Full Name

http://schemas.microsoft.com/cdo/workflow/adhocflows

Name Constant

cdowfAdhocFlows

OLE DB Type

DBTYPE_I1

Example

0 (PreventAdhocFlows)

See Also

cdowfAdhocFlows Enumeration


audittrail Field

A string of comma-separated values listing the states and actions through which a process instance has transitioned.

This property corresponds directly to the AuditTrail property on the IProcessInstance interface, in the CDOWF type library. Applications running directly on the server find it simpler to use this CDOWF interface, rather than manipulating the property directly. Applications that access the server remotely need to directly update the store property.

Full Name

http://schemas.microsoft.com/cdo/workflow/audittrail

Name Constant

CdoWfAuditTrail

OLE DB Type

DBTYPE_WSTR

Example

Date, Time, Importance, URL, Author, Description

3/22/99, 11:58, 2,,,Approved 3/22/99, 3:05, 2,,,Submitted to Accounts Payable


audittrailprovider Field

This is the COM class identifier (CLSID) of the object used by a workflow to build the audit trail.

This property corresponds directly to the AuditTrailProvider property on the IProcessDefinition interface, in the CDOWF type library. Applications running directly on the server find it simpler to use this CDOWF interface, rather than manipulating the property directly. Applications that access the server remotely need to directly update the store property.

Full Name

http://schemas.microsoft.com/cdo/workflow/audittrailprovider

Name Constant

cdowfAuditTrailProvider

OLE DB Type

DBTYPE_WSTR

Example

{CD001007-8B95-11D1-82DB-00C04FB1625D}

(CDOWF.AuditTrailEventLog.1)


commonscripturl Field

Uniform Resource Locator (URL) to the common script, for a process definition. If the process definition item contains the common script, this field is empty or contains the string file://self.

This property corresponds directly to the CommonScriptURL property on the IProcessDefinition interface, in the CDOWF type library. Applications running directly on the server find it simpler to use this CDOWF interface, rather than manipulating the property directly. Applications that access the server remotely need to directly update the store property.

Full Name

http://schemas.microsoft.com/cdo/workflow/commonscripturl

Name Constant

cdowfCommonScriptURL

OLE DB Type

DBTYPE_WSTR

Example

"c:\mycommonscript.txt"

© 2000-2001 Microsoft Corporation. All rights reserved.


currentstate Field

Current state of a workflow, expressed as a string containing any character. Read-only to all except the workflow engine. enforced by per-property access control list (ACL).

This property corresponds directly to the CurrentState property on the IProcessInstance interface, in the CDOWF type library. Applications running directly on the server find it simpler to use this CDOWF interface, rather than manipulating the property directly. Applications that access the server remotely need to directly update the store property.

Full Name

http://schemas.microsoft.com/cdo/workflow/currentstate

Name Constant

cdowfCurrentState

OLE DB Type

DBTYPE_WSTR

Example

Approved, Rejected, Complete, Waiting for Approval, 1234, Fired


defaultprocdefinition Field

URL to the default process definition for this application or folder.

The workflow engine looks for the value of the defaultprocdefinition field in the OnsyncSave registration item for the folder.

Full Name

http://schemas.microsoft.com/cdo/workflow/defaultprocdefinition

Name Constant

cdowfDefaultProcessDefinitionURL

OLE DB Type

DBTYPE_WSTR

Example

http://servername/Public/foldername/procdefname.ext


designtool Field

String used by workflow design tools to stamp any identifying information they need onto a Process Definition item.

This property corresponds directly to the DesignTool property on the IProcessDefinition interface, in the CDOWF type library. Applications running directly on the server find it simpler to use this CDOWF interface, rather than manipulating the property directly. Applications that access the server remotely need to directly update the store property.

Full Name

http://schemas.microsoft.com/cdo/workflow/designtool

Name Constant

cdowfDesignTool

OLE DB Type

DBTYPE_WSTR

Example

"Microsoft Workflow Designer for Exchange 2000 Server 1.0.61"


disablesuccessentries Field

The workflow event sink looks for this property in the OnsyncSave registration item for the folder. The value of the disablesuccessentries field tells the event sink whether or not to add audit trail entries for successful workflow transitions.

Full Name

http://schemas.microsoft.com/cdo/workflow/disablesuccessentries

Name Constant

cdowfDisableSuccessEntries

OLE DB Type

DBTYPE_BOOL

Example

0 (False)


enabledebug Field

The workflow event sink looks for this property in the OnsyncSave registration item for the folder. The value of the enabledebug field tells the event sink whether or not to instantiate the Just-in-Time script debugger for run-time errors.

Full Name

http://schemas.microsoft.com/cdo/workflow/enabledebug

Name Constant

cdowfEnableDebug

OLE DB Type

DBTYPE_BOOL

Example

1 (True)


expirytime Field

Time and date that a ProcessInstance will expire. The shortest interval is 15 minutes. The expirytime field is read-only to all except the workflow engine.

Full Name

http://schemas.microsoft.com/cdo/workflow/expirytime

Name Constant

cdowfExpiryTime

OLE DB Type

DBTYPE_FILETIME

Example

12/02/99 12:00


mode Field

The value of the mode field indicates under which workflow security mode a workflow process definition should be run.

This property corresponds directly to the Mode property on the IProcessDefinition interface, in the CDOWF type library. Applications running directly on the server find it simpler to use this CDOWF interface, rather than manipulating the property directly. Applications that access the server remotely need to directly update the store property.

Full Name

http://schemas.microsoft.com/cdo/workflow/mode

Name Constant

cdowfSecurityMode

OLE DB Type

DBTYPE_I4

Example

1 (cdowfRestrictedMode)


parentprocinstance Field

Created in outgoing WorkflowMessage. Consists of the permanent URL to the parent workflow process. Included on WorkflowMessage replies; used to correlate incoming message to process instance.

Full Name

http://schemas.microsoft.com/cdo/workflow/parentprocinstance

Name Constant

cdowfParentProcessInstance

OLE DB Type

DBTYPE_WSTR

© 2000-2001 Microsoft Corporation. All rights reserved.


processdefinition Field

URL that points to the ProcessDefinition item used by the current ProcessInstance. The URL file://self indicates an embedded, ad-hoc process definition.

This property corresponds directly to the ProcessDefinition property on the IProcessInstance interface, in the CDOWF type library. Applications running directly on the server find it simpler to use this CDOWF interface, rather than manipulating the property directly. Applications that access the server remotely need to directly update the store property.

Full Name

http://schemas.microsoft.com/cdo/workflow/processdefinition

Name Constant

cdowfProcessDefinitionURL

OLE DB Type

DBTYPE_WSTR

Example

http://servername/Public/foldername/procdefname.ext


response Field

Included in WorkflowMessage replies. A string that contains the user's voting response (for example: approved, rejected, and so on). This string is added to the Tracking Table.

Full Name

http://schemas.microsoft.com/cdo/workflow/response

Name Constant

cdowfResponse

OLE DB Type

DBTYPE_WSTR

© 2000-2001 Microsoft Corporation. All rights reserved.


trackingtablexml Field

This property corresponds directly to the TrackingTable property on the IProcessInstance interface, in the CDOWF type library. Applications running directly on the server find it simpler to use this CDOWF interface, rather than manipulating the property directly. Applications that access the server remotely need to directly update the store property.

Full Name

http://schemas.microsoft.com/cdo/workflow/trackingtablexml

Name Constant

cdowfTrackingTableXML

OLE DB Type

DBTYPE_WSTR

© 2000-2001 Microsoft Corporation. All rights reserved.


workflowmessageid Field

Created as part of an outgoing WorkflowMessage. Also included on WorkflowMessage replies and used to match responses to rows in the Tracking Table.

Full Name

http://schemas.microsoft.com/cdo/workflow/workflowmessageid

Name Constant

cdowfMessageID

OLE DB Type

DBTYPE_WSTR

© 2000-2001 Microsoft Corporation. All rights reserved.


Error Codes

The following topics describe the custom error codes used by CDO for Exchange 2000 Server (CDOEX) and Collaboration Data Objects Workflow (CDOWF).

CDO for Exchange 2000 Server Error Codes

CDO Workflow for Exchange 2000 Server Error Codes

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


CDO for Exchange 2000 Server Error Codes

This section contains the custom error codes used by CDO. All of these values are available as constants in the type library CdoErrorCodes module.

Error codes are 32-bit values whose structure is as follows:

   3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
  +---+-+-+-----------------------+-------------------------------+
  |Sev|C|R|     Facility          |               Code            |
  +---+-+-+-----------------------+-------------------------------+

Each error code consists of the following elements, as illustrated in the structure:

  • Sev—The severity code, which is one of the following values:
    • 00—Success
    • 01—Informational
    • 10—Warning
    • 11—Error
  • C—The customer code flag.
  • R—A reserved bit.
  • Facility—The facility code.
  • Code—The facility's status code.

The following table presents the custom error codes used by CDO.

Error Name | Value | Remarks
CDO_E_UNCAUGHT_EXCEPTION | 0x80040201L | Exception %1 was generated at address %2.
CDO_E_NOT_OPENED | 0x80040202L | No data source has been opened for the object.
CDO_E_UNSUPPORTED_DATASOURCE | 0x80040203L | The object does not support this type of data source.
CDO_E_INVALID_PROPERTYNAME | 0x80040204L | The object does not support the requested property name or namespace.
CDO_E_PROP_UNSUPPORTED | 0x80040205L | The object does not support the requested property.
CDO_E_INACTIVE | 0x80040206L | The object is not active. It may have been deleted or it may not have been opened.
CDO_E_NO_SUPPORT_FOR_OBJECTS | 0x80040207L | The object does not support storing persistent state information for objects.
CDO_E_NOT_AVAILABLE | 0x80040208L | The requested property or feature, while supported, is not available at this time or in this context.
CDO_E_NO_DEFAULT_DROP_DIR | 0x80040209L | No default drop directory has been configured for this server.
CDO_E_SMTP_SERVER_REQUIRED | 0x8004020AL | The SMTP server name is required, and was not found in the configuration source.
CDO_E_NNTP_SERVER_REQUIRED | 0x8004020BL | The NNTP server name is required, and was not found in the configuration source.
CDO_E_RECIPIENT_MISSING | 0x8004020CL | At least one recipient is required, but none were found.
CDO_E_FROM_MISSING | 0x8004020DL | At least one of the From or Sender fields is required, and neither was found.
CDO_E_SENDER_REJECTED | 0x8004020EL | The server rejected the sender address. The server response was: %1.
CDO_E_RECIPIENTS_REJECTED | 0x8004020FL | The server rejected one or more recipient addresses. The server response was: %1.
CDO_E_NNTP_POST_FAILED | 0x80040210L | The message could not be posted to the NNTP server. The transport error code was %2. The server response was: %1.
CDO_E_SMTP_SEND_FAILED | 0x80040211L | The message could not be sent to the SMTP server. The transport error code was %2. The server response was: %1.
CDO_E_CONNECTION_DROPPED | 0x80040212L | The transport lost its connection to the server.
CDO_E_FAILED_TO_CONNECT | 0x80040213L | The transport failed to connect to the server.
CDO_E_INVALID_POST | 0x80040214L | The Subject, From, and Newsgroup fields are all required, and one or more was not found.
CDO_E_AUTHENTICATION_FAILURE | 0x80040215L | The server rejected the logon attempt due to authentication failure. The server response was: %1.
CDO_E_INVALID_CONTENT_TYPE | 0x80040216L | The content type was not valid in this context. For example, the root of an MHTML message must be an HTML document.
CDO_E_LOGON_FAILURE | 0x80040217L | The transport was unable to log on to the server.
CDO_E_HTTP_NOT_FOUND | 0x80040218L | The requested resource could not be found. The server response was: %1.
CDO_E_HTTP_FORBIDDEN | 0x80040219L | Access to the requested resource is denied. The server response was: %1.
CDO_E_HTTP_FAILED | 0x8004021AL | The HTTP request failed. The server response was: %1.
CDO_E_MULTIPART_NO_DATA | 0x8004021BL | This is a multipart body part. It has no content other than the body parts contained within it.
CDO_E_INVALID_ENCODING_FOR_MULTIPART | 0x8004021CL | Multipart body parts must be encoded as 7bit, 8bit, or binary.
CDO_E_PROP_NOT_FOUND | 0x8004021EL | The requested property was not found.
CDO_E_INVALID_SEND_OPTION | 0x80040220L | The "SendUsing" configuration value is invalid.
CDO_E_INVALID_POST_OPTION | 0x80040221L | The "PostUsing" configuration value is invalid.
CDO_E_NO_PICKUP_DIR | 0x80040222L | The pickup directory path is required and was not specified.
CDO_E_NOT_ALL_DELETED | 0x80040223L | One or more messages could not be deleted.
CDO_E_NO_METHOD | 0x80040224L | The requested operation is not available on the underlying object.
CDO_E_PROP_READONLY | 0x80040227L | The property is read-only.
CDO_E_PROP_CANNOT_DELETE | 0x80040228L | The property cannot be deleted.
CDO_E_BAD_DATA | 0x80040229L | Data written to the object is inconsistent or invalid.
CDO_E_PROP_NONHEADER | 0x8004022AL | The requested property is not in the mail header namespace.
CDO_E_INVALID_CHARSET | 0x8004022BL | The requested character set is not installed on the computer.
CDO_E_ADOSTREAM_NOT_BOUND | 0x8004022CL | The ADO stream has not been opened.
CDO_E_CONTENTPROPXML_NOT_FOUND | 0x8004022DL | The content properties are missing.
CDO_E_CONTENTPROPXML_WRONG_CHARSET | 0x8004022EL | Content properties XML must be encoded using UTF-8.
CDO_E_CONTENTPROPXML_PARSE_FAILED | 0x8004022FL | Failed to parse content properties XML.
CDO_E_CONTENTPROPXML_CONVERT_FAILED | 0x80040230L | Failed to convert a property from XML to a requested type.
CDO_E_NO_DIRECTORIES_SPECIFIED | 0x80040231L | No directories were specified for resolution.
CDO_E_DIRECTORIES_UNREACHABLE | 0x80040232L | Failed to resolve against one or more of the specified directories.
CDO_E_BAD_SENDER | 0x80040233L | Could not find the Sender's mailbox.
CDO_E_SELF_BINDING | 0x80040234L | Binding to self is not allowed.
CDO_E_BAD_ATTENDEE_DATA | 0x80040235L | Data of the Attendees in the object is inconsistent or invalid. This error occurs when more than one attendee has the IsOrganizer property set to TRUE.
CDO_E_ARGUMENT1 | 0x80044000L | The first argument is invalid.
CDO_E_ARGUMENT2 | 0x80044001L | The second argument is invalid.
CDO_E_ARGUMENT3 | 0x80044002L | The third argument is invalid.
CDO_E_ARGUMENT4 | 0x80044003L | The fourth argument is invalid.
CDO_E_ARGUMENT5 | 0x80044004L | The fifth argument is invalid.
CDO_E_NOT_FOUND | 0x800CCE05L | The requested body part was not found in this message.
CDO_E_INVALID_ENCODING_TYPE | 0x800CCE1DL | The content encoding type is invalid.


CDO Workflow for Exchange 2000 Server Error Codes

This section contains the custom error codes used by Collaboration Data Objects Workflow (CDOWF). All of these values are available as constants in the CdoWfErrors type library module.

Error values are 32 bit values whose structure is depicted here:

   3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
  +---+-+-+-----------------------+-------------------------------+
  |Sev|C|R|     Facility          |               Code            |
  +---+-+-+-----------------------+-------------------------------+

Reading this depiction from left-to-right, the severity code, Sev, is one of the following values:

  • 00 - Success
  • 01 - Informational
  • 10 - Warning
  • 11 - Error

Followed by:

C — The customer code flag.

R — A reserved bit.

Facitlity — The facility code.

Code — The facility's status code.

Error Name | Value | Remarks
CDOWF_E_UNCAUGHT_EXCEPTION | FF8004060B | Uncaught exception.
CDOWF_E_ADVANCE_EMPTY_CURSTATE | FF8004060C | Advance called without a current state, and the event type is not OnCreate.
CDOWF_CANT_CONVERT_SMTP_TO_SID | FF8004060D | The e-mail address <%1> could not be mapped to a user account.
CDOWF_CANT_OBTAIN_DOMAINEXSERVERS_SID | FF8004060E | Cannot obtain the security descriptor of the Domain EXServers group.
CDOWF_E_EMPTY_NEWSTATE | FF8004060F | ActionTable row %1: NewState must be valid.
CDOWF_E_NONEMPTY_NEWSTATE | FF80040610 | ActionTable row %1: NewState must be empty.
CDOWF_E_EMPTY_CURSTATE | FF80040611 | ActionTable row %1: State must be valid.
CDOWF_E_NONEMPTY_CURSTATE | FF80040612 | ActionTable row %1: State must be empty.
CDOWF_E_INVALID_EVENTTYPE | FF80040613 | ActionTable row %1: Invalid event type.
CDOWF_ADVANCE_INVALID_EVENTTYPE | FF80040614 | Invalid event type.
CDOWF_E_EMPTY_EVENTTYPE | FF80040615 | ActionTable row %1: Event type required.
CDOWF_E_EMPTY_CONDITION | FF80040616 | ActionTable row %1: Condition required.
CDOWF_E_ROW_INVALID_FLAGS | FF80040617 | ActionTable row %1: Flags invalid.
CDOWF_E_ROW_INVALID_EXPIRY | FF80040618 | ActionTable row %1: Expiry interval invalid.
CDOWF_E_PROCDEF_MISSING | FF80040619 | This ProcessInstance method requires a valid ProcessDefinition to be loaded.
CDOWF_E_SAVE_ITEM | FF8004061A | Cannot save the item to a row that is a collection.
CDOWF_E_OPEN_ITEM | FF8004061B | Cannot open the item on a row that is a collection.
CDOWF_EMPTY_ACTIONTABLE | FF8004061C | ActionTable does not exist on this ProcessDefinition.
CDOWF_E_INVALID_FLAGS | FF8004061D | The supplied transition flags are not valid.
CDOWF_E_INVALID_COND_RESULT | FF8004061E | A condition must return either true or false.
CDOWF_E_WFSESSION_PROPERTY_NOT_FOUND | FF8004061F | The requested WorkflowSession property does not exist: %1.
CDOWF_E_INVALID_COMMONSCRIPT | FF80040620 | The common script specified on the ProcessDefinition was either incorrect or couldn't be loaded: <%1>.
CDOWF_ERROR_READING_COMMONSCRIPT | FF80040621 | The common script specified on the ProcessDefinition couldn't be loaded.
CDOWF_E_OPERATION_DISALLOWED | FF80040622 | The user is not allowed to make this transition because the user is not a member of the role specified in the transition access control list (ACL), or that role does not exist.
CDOWF_E_TRANSITIONACL | FF80040623 | A transition ACL was specified for this transition, but there was an error retrieving the role, or the role does not exist.
CDOWF_E_TRANSITIONACL_NO_USE_ONEXPIRY | FF80040624 | ActionTable row %1: Transition ACLs in ActionTable rows of event type OnExpiry are not enforced.
CDOWF_E_COM_REQUIRES_PRIV | FF80040625 | Condition, action, or compensation COM objects require privileged mode to run.
CDOWF_E_BAD_ACTIONTABLE | FF80040626 | Cannot load row from ActionTable due to missing column or bad fields.
CDOWF_E_PI_NOT_BOUND | FF80040627 | Calling Advance requires that ProcessInstance be bound to a DataSource. Make sure that either Open or OpenObject was called.
CDOWF_E_INVALID_MODE | FF80040628 | The mode specified in ProcessDefinition is invalid.
CDOWF_E_PRIVILEGED_DENIED | FF80040629 | The ProcessDefinition requests privileged mode, but that mode is not allowed because the author/modifier of the ProcessDefinition document, the event registration document, or the common script document is not in the Privileged Workflow Authors role.
CDOWF_E_ROLES_DISABLED | FF8004062A | The workflow event sink could not run because the Enforce Access Checks check box is not checked on its COM+ application property page.
CDOWF_E_DUPLICATE_ORDER | FF8004062B | ActionTable is invalid because of duplicate evaluation order entries.
CDOWF_E_ROW_DUPLICATE_ORDER | FF8004062C | ActionTable row %1: Duplicate evaluation order entry.
CDOWF_E_ROW_INVALID_SEQUENCENUMBER | FF8004062D | ActionTable row %1: Invalid evaluation order entry.
CDOWF_E_ROW_INVALID_SEQUENCING | FF8004062E | ActionTable row %1: For each (STATE, EVENTTYPE) pair, EvaluationOrder should consistently be either empty or not.
CDOWF_E_AT_NOTBOUND | FF8004062F | The audit trail object is not bound.
CDOWF_E_NOTBOUND | FF80040630 | The DataSource object is not bound to a row or record.
CDOWF_MDBROLE_DLL_NOT_LOADED | FF80040631 | The role support DLL (mdbrole.dll) could not be initialized.
CDOWF_CANT_EXTRACT_SMTPADDR | FF80040632 | The "From" field of the received message did not contain a valid SMTP address: %1.
CDOWF_EVENTSINK_ALREADY_REGISTERED | FF80040633 | There is already a workflow event sink registered to fire for this folder.
CDOWF_EVENTSINK_EVENT_NOT_SUPPORTED | FF80040634 | The workflow event sink does not support one of the requested EventMethods. Only onsyncsave, onsyncdelete, and ontimer are supported.
CDOWF_EVENTSINK_REGISTRATION_NOT_ALLOWED | FF80040635 | The user who attempted to register workflow is not a member of the "Can Register Workflow" role.
CDOWF_EVENTSINK_NO_GLOBAL | FF80040636 | The workflow event sink cannot be registered with MatchScope ANY.
CDOWF_CONNECTION_NOT_ALLOWED | FF80040637 | The ActiveConnection property is only available to privileged mode workflows.
CDOWF_ADVANCE_NO_RECEIVED_MESSAGE | FF80040638 | Advance was called with OnReceive, but there was no received message passed in.
CDOWF_ERROR_READING_ACTIONTABLE | FF80040639 | There was an error reading the ActionTable.
CDOWF_INVALID_EXPIRY_INTERVAL | FF8004063A | The ActionTable contains an invalid expiry interval.
CDOWF_INVALID_EVALUATION_ORDER | FF8004063B | The ActionTable contains an invalid evaluation order.
CDOWF_NO_PERM_URL | FF8004063C | SendWorkflowMessage cannot be called during an OnCreate transition.
CDOWF_NO_CORRELATE_PERM_DENIED | FF8004063D | Correlation failed due to insufficient permissions. Check that the workflow event sink has read/write permissions to all items in this folder.
CDOWF_INVALID_USER_ID | FF8004063E | The username was invalid: [%1].
CDOWF_INVALID_USER_SID | FF8004063F | The SID was invalid.
CDOWF_CANT_GET_SAVER_SMTP_EMAIL | FF80040640 | WorkflowSession.Sender: Cannot obtain SMTP address for current user.
CDOWF_INVALID_RESPONSE | FF80040641 | The correlated message contained a response that was not a string.
CDOWF_INVALID_WORKFLOWMESSAGEID | FF80040642 | The correlated message contained a tracking ID that was either not a string or didn't match any entry in the TrackingTable.
CDOWF_NO_CONDS_MATCHED | FF80040643 | Advance was called with event type %1, but no matching actions were found.
CDOWF_UNKNOWN_ERROR | FF80040644 | Unknown error: %1.
CDOWF_INVALID_PROCDEFINITION_URL | FF80040645 | The ProcessDefinition URL is invalid: <%1>.
CDOWF_CANT_CREATE_AUDITTRAIL | FF80040646 | The audit trail specified on the ProcessDefinition was either incorrect or couldn't be created: %1.
CDOWF_INVALID_ADHOC_FLAG | FF80040647 | The adhoc flag specified on the ProcessDefinition is not valid.
CDOWF_ERROR_OUTSIDE_EVENTSINK | FF80040648 | Workflow state transition wasn't saved. Please make sure that a user performing state change has appropriate permissions.
CDOWF_DEFAULTPD_REQUIRED | FF80040649 | The default ProcessDefinition URL on the event registration item is empty. The new process instance cannot be created.
CDOWF_DEFAULTPD_INVALID | FF8004064A | The default ProcessDefinition URL on the event registration item is not valid. The new process instance cannot be created.
CDOWF_ADHOC_DISALLOWED | FF8004064B | Adhoc workflows are disallowed for this folder. The new process instance cannot be created.
CDOWF_ADHOC_ONLY | FF8004064C | Only adhoc workflows are allowed for this folder. The new process instance cannot be created.
CDOWF_ONLY_HIDDEN_PD | FF8004064D | The ProcessDefinitionURL must point to a hidden item. The new process instance cannot be created.
CDOWF_MEMBER_NOT_FOUND | FF8004064E | The specified member of the collection was not found.
CDOWF_INVALID_NAME_TYPE | FF8004064F | The type must be either EmailAddress or Role.
CDOWF_INVALID_NAME | FF80040650 | The member name could not be mapped to a SID based on the given type.
CDOWF_INVALID_ROLE_SID | FF80040651 | The role sid could not be mapped to a role.
CDOWF_EVENTSINK_HAS_NO_MAILBOX | FF80040652 | The Workflow is running under an account that doesn't have a mailbox, or the Connection passed to Advance is empty.
CDOWF_MESSAGE_DELETE_NOT_ALLOWED | FF80040654 | An action can only delete the received message during an OnReceive event type.
CDOWF_INVALID_FOLDER_URL | FF80040655 | The format of workflow folder URL is invalid.
CDOWF_CANT_OBTAIN_FOLDERADDR | FF80040656 | The e-mail address of the workflow folder cannot be obtained: the workflow folder should be either an inbox or a mail-enabled public folder.
CDOWF_NO_ACTIVE_DIRECTORY | FF80040657 | Active Directory™ is not available.
CDOWF_EXPIRATION_QUERY_FAILED | FF80040658 | A periodic query for expired workflow items has failed. The workflow event sink might be recursively registered in a Public Folder Tree that does not support recursive queries.
CDOWF_NO_PARENT_PROCINSTANCE | FF80040659 | Incoming mail message from <%1> could not be correlated to an existing ProcessInstance. The ProcessInstance specified (<%2>) no longer exists.
CDOWF_CANT_CONVERT_SMTP_TO_REQUESTED_ATTR | FF8004065A | A call to GetUserProperty failed. The specified e-mail address <%1> could not be matched to an Active Directory entry.


WMI Classes

The Microsoft® Exchange 2000 Web Storage System provides a set of Windows® Management Instrumentation (WMI) classes for use in custom system monitoring and diagnostic applications. Complete information about creating applications using Windows Management Instrumentation is available on MSDN.

Exchange 2000 Server installs three WMI providers: ExchangeQueueProvider, ExchangeRoutingTableProvider, and ExchangeClusterProvider. The WMI providers implement five WMI classes, listed in the following table.

WMI class | Provider and description
ExchangeLink | ExchangeQueueProvider. Supplies information about message-handling links between mail servers. A link can contain zero or more ExchangeQueue objects, depending on the current message traffic along the link. In the Exchange management user interface, these links are called queues.
ExchangeQueue | ExchangeQueueProvider. Supplies information about the dynamic queues created to represent the transfer of individual messages between mail servers. An ExchangeQueue is part of an ExchangeLink. ExchangeQueue objects are not the same as queues listed in the Exchange management user interface.
ExchangeConnectorState | ExchangeRoutingTableProvider. Supplies status for an Exchange Connector.
ExchangeServerState | ExchangeRoutingTableProvider. Supplies information about an Exchange Server.
ExchangeClusterResource | ExchangeClusterProvider. Supplies status for an Exchange cluster resource.

Important Do not confuse a messaging queue as displayed in the Exchange management user interface with the the ExchangeQueue WMI class. Instances of the ExchangeLink WMI class correspond to the queues shown in the management user interface.

Namespace

The Exchange 2000 Server WMI providers use the following namespace:

\\.\root\cimv2\Applications\Exchange

Installation

The Exchange 2000 Server WMI providers are installed with the Exchange Management Components. The Exchange Management Components, and thus the WMI providers, are installed as part of the Exchange management user interface installation. The Exchange setup program registers the WMI providers and classes.

To remotely monitor a computer running Exchange 2000 Server using WMI, the client computer must have the Exchange Management Components installed, in addition to the base WMI requirements.

See Also

MSDN Windows Management Instrumentation start page


ExchangeLink

The ExchangeLink WMI class has properties that return information about message-handling links between mail servers. A link can contain zero or more ExchangeQueue objects, depending on the current message traffic along the link. In the Exchange management user interface, these links are called queues.

Class Name
ExchangeLink
Provider
ExchangeQueueProvider
Type
Dynamic
Namespace
\\.\root\cimv2\Applications\Exchange
Key Properties
ProtocolName
VirtualServerName
LinkName

Properties

The following table lists the properties for ExchangeLink.

Property | Description
ActionFreeze | Boolean Read-only When true, indicates that the link supports freezing messages in its queues. When true, represents the value 0x0002 in SupportedLinkActions.
ActionKick | Boolean Read-only When true, indicates that the link can trigger its queues to immediately retry transmitting waiting messages. When true, represents the value 0x0001 in SupportedLinkActions.
ActionThaw | Boolean Read-only When true, indicates that the link supports thawing messages in its queues. When true, represents the value 0x0004 in SupportedLinkActions.
ExtendedStateInfo | String Read-only Text description of the current link status.
GlobalStop | Boolean Read-only Whether the link is currently stopped.
IncreasingTime | Uint32 Read-only The amount of time, in seconds, that the number of messages waiting to be transferred by the link has been increasing.
LinkDN | String Read-only The distinguished name (DN) of the link in Active Directory.
LinkName | String Read-only Qualifiers: Key The name of the link.
NextScheduledConnection | Datetime Read-only The date and time when a connection will be attempted to transfer waiting messages.
NumberOfMessages | Uint32 Read-only The number of messages that are waiting for transmission across the link.
OldestMessage | Datetime Read-only The date and time when the oldest message that is still awaiting transmission was received into the link.
ProtocolName | String Read-only Qualifiers: Key The transmission protocol for the link.
SizeOfQueue | Uint64 Read-only The number of messages currently waiting to be transmitted by the link.
StateActive | Boolean Read-only When true, indicates that the link is active. When true, represents the value 0x0001 in StateFlags.
StateFlags | Uint32 Read-only The state of the link. The individual bits of this property are available as the link State… and Type… properties listed in this table.
StateReady | Boolean Read-only When true, indicates that the link is ready to accept new messages. When true, represents the value 0x0002 in StateFlags.
StateRemote | Boolean Read-only When true, indicates that the link is on a remote server, as compared with the link residing on the server being monitored. When true, represents the value 0x0010 in StateFlags.
StateRetry | Boolean Read-only When true, indicates that the link is currently retrying a message transmission that was unsuccessful. When true, represents the value 0x0004 in StateFlags.
StateScheduled | Boolean Read-only When true, indicates that the link is scheduled for periodic activation, as compared with asynchronous, on-demand activation. When true, represents the value 0x0008 in StateFlags.
SupportedLinkActions | Uint32 Read-only The actions supported by the link at the current time. The individual bits of this property are available as the Action… properties listed in this table.
TypeCurrentlyUnreachable | Boolean Read-only When true, indicates that the link is currently unable to reach the destination server. When true, represents the value 0x0200 in StateFlags.
TypeDeferredDelivery | Boolean Read-only When true, indicates that the link has deferred delivery of the currently pending message, due to some transmission problem. When true, represents the value 0x0400 in StateFlags.
TypeInternal | Boolean Read-only Reserved for internal use. Represents the value 0x0800 in StateFlags.
TypeLocalDelivery | Boolean Read-only When true, indicates that the link is currently handling a local message delivery. When true, represents the value 0x0040 in StateFlags.
TypePendingCategorization | Boolean Read-only When true, indicates that the link is currently determining the message category of the next message waiting to be transmitted. When true, represents the value 0x0100 in StateFlags.
TypePendingRouting | Boolean Read-only When true, indicates that the link is currently determining the routing of the next message waiting to be transmitted. When true, represents the value 0x0080 in StateFlags.
TypeRemoteDelivery | Boolean Read-only When true, indicates that the link is currently handling a remote message delivery. When true, represents the value 0x0020 in StateFlags.
Version | Uint32 Read-only The Exchange software version number.
VirtualMachine | String Read-only The name of the virtual machine that is the source of the link.
VirtualServerName | String Read-only Qualifiers: Key The value of this property is the integer number of the virtual machine that is the source of the link. This number is the the Active Directory common name (CN) for the virtual server object.

Remarks

This class has no methods and no intrinsic events. All properties are read-only.


ExchangeQueue

The ExchangeQueue WMI class has properties that return information about the dynamic queues created to represent the transfer of individual messages between mail servers. An ExchangeQueue is part of an ExchangeLink. ExchangeQueue objects are not the same as queues listed in the Exchange management user interface.

Class Name
ExchangeQueue
Provider
ExchangeQueueProvider
Type
Dynamic
Namespace
\\.\root\cimv2\Applications\Exchange
Key Properties
ProtocolName
VirtualServerName
LinkName
QueueName

Properties

The following table lists the properties for ExchangeQueue.

Property | Description
CanEnumAll | Boolean Read-only When true, indicates that the queue can enumerate all the messages it has waiting for transmission. When true, represents the value 0x0200 in MsgEnumFlagsSupported.
CanEnumFailed | Boolean Read-only When true, indicates that the queue can enumerate the messages it has waiting for transmission that it was unable to transfer. When true, represents the value 0x0100 in MsgEnumFlagsSupported.
CanEnumFirstNMessages | Boolean Read-only When true, indicates that the queue can enumerate the first N messages it has waiting for transmission. When true, represents the value 0x0001 in MsgEnumFlagsSupported.
CanEnumFrozen | Boolean Read-only When true, indicates that the queue can enumerate messages it has waiting for transmission that have been frozen. When true, represents the value 0x0020 in MsgEnumFlagsSupported.
CanEnumInvertSense | Boolean Read-only When true, indicates that the queue can enumerate messages it has waiting for transmission that do not match the criteria requested. For example, requesting the oldest messages while inverting the request sense would return the newest messages. When true, represents the value 0x0400 in MsgEnumFlagsSupported.
CanEnumLargerThan | Boolean Read-only When true, indicates that the queue can enumerate the messages it has waiting for transmission that are larger than a specified value. When true, represents the value 0x0008 in MsgEnumFlagsSupported.
CanEnumNLargestMessages | Boolean Read-only When true, indicates that the queue can enumerate the specified number of the largest messages it has waiting for transmission. When true, represents the value 0x0040 in MsgEnumFlagsSupported.
CanEnumNOldestMessages | Boolean Read-only When true, indicates that the queue can enumerate the specified number of the oldest messages it has waiting for transmission. When true, represents the value 0x0080 in MsgEnumFlagsSupported.
CanEnumOlderThan | Boolean Read-only When true, indicates that the queue can enumerate the messages it has waiting for transmission that arrived before a specified date and time. When true, represents the value 0x0010 in MsgEnumFlagsSupported.
CanEnumRecipient | Boolean Read-only When true, indicates that the queue can enumerate the recipients of messages it has waiting for transmission. When true, represents the value 0x0004 in MsgEnumFlagsSupported.
CanEnumSender | Boolean Read-only When true, indicates that the queue can enumerate the senders of messages it has waiting for transmission. When true, represents the value 0x0002 in MsgEnumFlagsSupported.
GlobalStop | Boolean Read-only Whether the queue is currently stopped.
IncreasingTime | Uint32 Read-only The amount of time, in seconds, that the number of messages waiting to be transferred by the queue has been increasing.
LinkName | String Read-only Qualifiers: Key The name of the link that this queue is contained in.
MsgEnumFlagsSupported | Unit32 Read-only A bit-mapped set of flags indicating what types of objects can be enumerated. The individual bits of this property are available as the queue CanEnum… properties listed in this table.
NumberOfMessages | Uint32 Read-only The number of messages that are waiting for transmission by the queue.
ProtocolName | String Read-only Qualifiers: Key The transmission protocol for the queue.
QueueName | String Read-only Qualifiers: Key The name of the queue.
SizeOfQueue | Uint32 Read-only The amount of space reserved for the queue for holding messages that are waiting to be transferred.
Version | Uint32 Read-only The Exchange software version number.
VirtualMachine | String Read-only The name of the virtual machine that is the source of the link.
VirtualServername | String Read-only Qualifiers: Key The value of this property is the integer number of the virtual machine that is the source of the queue. This number is the the Active Directory common name (CN) for the virtual server object.


ExchangeConnectorState

The ExchangeConnectorState WMI class has properties that return information about an Exchange connector.

Class Name
ExchangeConnectorState
Provider
ExchangeRoutingTableProvider
Type
Dynamic
Namespace
\\.\root\cimv2\Applications\Exchange
Key Properties
DN

Properties

The following table lists the properties for ExchangeConnectorState.

Property | Description
DN | String Read-only Qualifiers: Key Indicates the Active Directory distinguished name (DN) of the Exchange Connector object.
GroupDN | String Read-only The distinguished name of the Active Directory group of which the user account as which the Exchange Connector runs is a member.
GroupGUID | String Read-only The globally-unique identifier (GUID) of the Active Directory group of which the user account as which the Exchange Connector runs is a member.
GUID | String Read-only The globally-unique identifier (GUID) of the Exchange Connector.
IsUp | Boolean Read-only When true, indicates that the Exchange Connector is currently operating normally.
Name | String Read-only The name of the Exchange Connector.

Remarks

This class has no methods and no intrinsic events. All properties are read-only.


ExchangeServerState

Class Name
ExchangeServerState
Provider
ExchangeRoutingTableProvider
Type
Dynamic
Namespace
\\.\root\cimv2\Applications\Exchange
Key Properties
DN

Properties

The ExchangeServerState WMI class has properties that return information about the computer running Exchange 2000.

Property | Description
ClusterState | Uint8 Read-only Values: 0=Unknown, 1=OK, 2=Warning, 3=Error Indicates the current state of the Exchange server cluster. Paired with the ClusterStateString property.
ClusterStateString | String Read-only Values: "Unknown", "OK", "Warning", "Error" Indicates the current state of the Exchange server cluster. Paired with the ClusterState property.
CPUState | Uint8 Read-only Values: 0=Unknown, 1=OK, 2=Warning, 3=Error Indicates the current state of the CPU on the Exchange server. Paired with the CPUStateString property.
CPUStateString | String Read-only Values: "Unknown", "OK", "Warning", "Error" Indicates the current state of the CPU on the Exchange server. Paired with the CPUState property.
DisksState | Uint8 Read-only Values: 0=Unknown, 1=OK, 2=Warning, 3=Error Indicates the current state of the disk storage on the Exchange server. Paired with the DisksStateString property.
DisksStateString | String Read-only Values: "Unknown", "OK", "Warning", "Error" Indicates the current state of the disk storage on the Exchange server. Paired with the DisksState property.
DN | String Read-only Qualifiers: Key Indicates the Active Directory distinguished name (DN) of the Exchange server object.
GroupDN | String Read-only The distinguished name of the Active Directory group of which the user account as which the Exchange server runs is a member.
GroupGUID | String Read-only The globally-unique identifier (GUID) of the Active Directory group of which the user account as which the Exchange server runs is a member.
GUID | String Read-only The globally-unique identifier (GUID) of the Exchange server.
MemoryState | Uint8 Read-only Values: 0=Unknown, 1=OK, 2=Warning, 3=Error Indicates the current state of the memory on the Exchange server. Paired with the MemoryStateString property.
MemoryStateString | String Read-only Values: "Unknown", "OK", "Warning", "Error" Indicates the current state of the meory on the Exchange server. Paired with the MemoryState property.
Name | String Read-only The name of the Exchange server.
QueuesState | Uint8 Read-only Values: 0=Unknown, 1=OK, 2=Warning, 3=Error Indicates the current state of the queues on the Exchange server. Paired with the QueuesStateString property.
QueuesStateString | String Read-only Values: "Unknown", "OK", "Warning", "Error" Indicates the current state of the queues on the Exchange server. Paired with the QueuesState property.
ServerMaintenance | Boolean Read-only When true, indicates that the server is currently unavailable because it is undergoing maintenance.
ServerState | Uint8 Read-only Values: 0=Unknown, 1=OK, 2=Warning, 3=Error Indicates the current state of the Exchange server. Paired with the ServerStateString property.
ServerStateString | String Read-only Values: "Unknown", "OK", "Warning", "Error" Indicates the current state of the Exchange server. Paired with the ServerState property.
ServicesState | Uint8 Read-only Values: 0=Unknown, 1=OK, 2=Warning, 3=Error Indicates the current state of the Exchange services running on the Exchange server. Paired with the ServicesStateString property.
ServicesStateString | String Read-only Values: "Unknown", "OK", "Warning", "Error" Indicates the current state of the Exchange services running on the Exchange server. Paired with the ServicesState property.
Unreachable | Boolean Read-only When true, indicates that the Exchange server is currently unreachable.

Remarks

This class has no methods and no intrinsic events. All properties are read-only.


ExchangeClusterResource

The ExchangeClusterResource WMI class has properties that return information about an Exchange cluster resource.

Class Name
ExchangeClusterResource
Provider
ExchangeClusterProvider
Type
Dynamic
Namespace
\\.\root\cimv2\Applications\Exchange
Key Properties
VirtualMachine
Name

Properties

The following table lists the properties for ExchangeClusterResource.

Property | Description
Name | String Read-only Qualifiers: Key The name of the Exchange cluster resource.
Owner | String Read-only The name of the cluster to which this resource belongs.
State | Uint32 Read-only The current state of the cluster resource.
Type | String Read-only The resource type.
VirtualMachine | String Read-only Qualifiers: Key The name of the virtual machine that is the source of the link.

Remarks

This class has no methods and no intrinsic events. All properties are read-only.


Web Storage System

The Web Storage System provides support for a variety of data access application programming interfaces (APIs) and protocols. The Web Storage System Schema offers a large number of predefined content classes and properties that you can use to define resources in the Web Storage System and as a basis for creating your own custom application schemas.

This section contains the following topics:

Web Storage System Schema

Web Storage System SQL

Exchange OLE DB Provider

Data Types and Mappings

Event Interfaces

WebDAV Reference

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Web Storage System Schema

The Web Storage System Schema consists of properties that define all resources in the store, including e-mail messages, appointments, folders, and contacts. The Web Storage System includes numerous predefined properties you can use in your applications. You can also extend the Web Storage System Schema by defining your own custom properties. This section lists the predefined properties in the Web Storage System Schema and describes how Messaging Application Programming Interface (MAPI) content classes map to content classes in the Web Storage System.

This section contains the following topics:

Content Classes

Content Class Mappings from MAPI

Properties by Namespace

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Content Classes

Every resource in the Web Storage System belongs to a content class, or category, which identifies the purpose of the resource. Every content class is associated with at least one Web Storage System Schema property related to the type of resource the content class describes. For example, the content class urn:content-classes:appointment has properties that are related to appointments.

The Web Storage System includes a number of predefined content classes that you can use in your applications. You can also define custom content classes and properties. This section lists the predefined Web Storage System content classes and their properties.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


urn:content-classes:appointment

The urn:content-classes:appointment content class defines properties for items that are appointments.

Extends
urn:content-classes:item
COM Prog ID
CDO.Appointment

Properties

urn:schemas:calendar:alldayevent

urn:schemas:contacts:billinginformation

urn:schemas:calendar:busystatus

http://schemas.microsoft.com/exchange/companies

urn:schemas:calendar:contact

urn:schemas:calendar:contacturl

urn:schemas:calendar:created

urn:schemas:calendar:descriptionurl

urn:schemas:calendar:dtend

urn:schemas:calendar:dtstamp

urn:schemas:calendar:dtstart

urn:schemas:calendar:duration

urn:schemas:calendar:exdate

urn:schemas:calendar:exrule

urn:schemas:calendar:geolatitude

urn:schemas:calendar:geolongitude

urn:schemas:httpmail:hasattachment

urn:schemas:httpmail:htmldescription

urn:schemas:calendar:instancetype

urn:schemas:calendar:lastmodified

urn:schemas:calendar:location

urn:schemas:calendar:locationurl

urn:schemas:calendar:meetingstatus

urn:schemas:calendar:method

http://schemas.microsoft.com/exchange/mileage

urn:schemas:httpmail:normalizedsubject

urn:schemas:httpmail:priority

urn:schemas:calendar:rdate

urn:schemas:calendar:recurrenceid

urn:schemas:calendar:recurrenceidrange

urn:schemas:calendar:reminderoffset

urn:schemas:calendar:replytime

urn:schemas:calendar:resources

urn:schemas:calendar:responserequested

urn:schemas:calendar:rrule

http://schemas.microsoft.com/exchange/sensitivity

urn:schemas:calendar:sequence

urn:schemas:mailheader:subject

urn:schemas:httpmail:subject

urn:schemas:httpmail:textdescription

urn:schemas:calendar:timezone

urn:schemas:calendar:timezoneid

urn:schemas:calendar:transparent

urn:schemas:calendar:uid


urn:content-classes:calendarfolder

The urn:content-classes:calendarfolder content class defines a set of properties for a folder that primarily contains appointment items.

Extends
urn:content-classes:folder
COM Prog ID
CDO.Folder

Expected Content Class

urn:content-classes:appointment


urn:content-classes:calendarmessage

The urn:content-classes:calendarmessage content class defines a set of properties for message items that contain meeting requests.

Extends
urn:content-classes:message
COM Prog ID
CDO.CalendarMessage

Properties

urn:schemas:calendar:method


urn:content-classes:contactfolder

The urn:content-classes:contactfolder content class defines a set of properties for a folder that primarily contains contact items.

Extends
urn:content-classes:folder
COM Prog ID
CDO.Folder

Expected Content Class

urn:content-classes:person


urn:content-classes:contentclassdef

The urn:content-classes:contentclassdef content class defines a set of properties for an item that defines a content class for the Microsoft® Web Storage System schema.

Extends
urn:schemas-microsoft-com:xml-data#ElementType
COM Prog ID
CDO.Item

Properties

urn:schemas-microsoft-com:exch-data:closedexpectedcontentclasses

urn:schemas-microsoft-com:exch-data:codebase

urn:schemas-microsoft-com:exch-data:comclassid

urn:schemas-microsoft-com:exch-data:comprogid

urn:schemas-microsoft-com:xml-data#element

urn:schemas-microsoft-com:exch-data:expected-content-class

urn:schemas-microsoft-com:exch-data:version

Property Defaults

None

© 2000-2001 Microsoft Corporation. All rights reserved.


urn:content-classes:document

The urn:content-classes:document content class defines a set of properties for an item that is a document such as a Microsoft® Word file.

Extends
urn:content-classes:item
COM Prog ID
CDO.Item

Properties

urn:schemas-microsoft-com:office:office#Author

urn:schemas-microsoft-com:office:office#Bytes

urn:schemas-microsoft-com:office:office#Category

urn:schemas-microsoft-com:office:office#Characters

urn:schemas-microsoft-com:office:office#Checked_x0020_by

urn:schemas-microsoft-com:office:office#Client

urn:schemas-microsoft-com:office:office#Comments

urn:schemas-microsoft-com:office:office#Company

urn:schemas-microsoft-com:office:office#Created

urn:schemas-microsoft-com:office:office#Date_x0020_completed

urn:schemas-microsoft-com:office:office#Department

urn:schemas-microsoft-com:office:office#Destination

urn:schemas-microsoft-com:office:office#Disposition

urn:schemas-microsoft-com:office:office#Division

urn:schemas-microsoft-com:office:office#Document_x0020_number

urn:schemas-microsoft-com:office:office#Editor

urn:schemas-microsoft-com:office:office#Forward_x0020_to

urn:schemas-microsoft-com:office:office#Group

urn:schemas-microsoft-com:office:office#HeadingPairs

urn:schemas-microsoft-com:office:office#HiddenSlides

urn:schemas-microsoft-com:office:office#Language

urn:schemas-microsoft-com:office:office#LastAuthor

urn:schemas-microsoft-com:office:office#LastPrinted

urn:schemas-microsoft-com:office:office#LastSaved

urn:schemas-microsoft-com:office:office#Lines

urn:schemas-microsoft-com:office:office#LinksUpToDate

urn:schemas-microsoft-com:office:office#MailStop

urn:schemas-microsoft-com:office:office#Manager

urn:schemas-microsoft-com:office:office#Matter

urn:schemas-microsoft-com:office:office#MultimediaClips

urn:schemas-microsoft-com:office:office#NameOfApplication

urn:schemas-microsoft-com:office:office#Notes

urn:schemas-microsoft-com:office:office#Office

urn:schemas-microsoft-com:office:office#Owner

urn:schemas-microsoft-com:office:office#Pages

urn:schemas-microsoft-com:office:office#Paragraphs

urn:schemas-microsoft-com:office:office#PartTitles

urn:schemas-microsoft-com:office:office#PresentationFormat

urn:schemas-microsoft-com:office:office#Project

urn:schemas-microsoft-com:office:office#Publisher

urn:schemas-microsoft-com:office:office#Purpose

urn:schemas-microsoft-com:office:office#Received

urn:schemas-microsoft-com:office:office#Recorded

urn:schemas-microsoft-com:office:office#Recorded_x0020_date

urn:schemas-microsoft-com:office:office#Reference

urn:schemas-microsoft-com:office:office#Revision

urn:schemas-microsoft-com:office:office#ScaleCrop

urn:schemas-microsoft-com:office:office#Security

urn:schemas-microsoft-com:office:office#Slides

urn:schemas-microsoft-com:office:office#Source

urn:schemas-microsoft-com:office:office#Status

urn:schemas-microsoft-com:office:office#Subject

urn:schemas-microsoft-com:office:office#Telephone_x0020_number

urn:schemas-microsoft-com:office:office#Template

urn:schemas-microsoft-com:office:office#ThumbNail

urn:schemas-microsoft-com:office:office#Title

urn:schemas-microsoft-com:office:office#TotalTime

urn:schemas-microsoft-com:office:office#Typist

urn:schemas-microsoft-com:office:office#Version

urn:schemas-microsoft-com:office:office#Words


urn:content-classes:dsn

The urn:content-classes:dsn content class defines a set of properties for an item that is a delivery status notification (DSN) message.

Extends
urn:content-classes:reportmessage
COM Prog ID
CDO.Message

Properties

None

© 2000-2001 Microsoft Corporation. All rights reserved.


urn:content-classes:folder

The urn:content-classes:folder content class defines a set of properties for a folder in the Web Storage System.

Extends
urn:content-classes:item
COM Prog ID
CDO.Folder

Properties

http://schemas.microsoft.com/exchange/adminfolderdescription

urn:schemas-microsoft-com:exch-data:baseschema

http://schemas.microsoft.com/exchange/contentexpiryagelimit

http://schemas.microsoft.com/exchange/deleteditemsagelimit

urn:schemas-microsoft-com:exch-data:expected-content-class

http://schemas.microsoft.com/exchange/folderadmingroup

http://schemas.microsoft.com/exchange/folderproxy

http://schemas.microsoft.com/exchange/foldersize

http://schemas.microsoft.com/exchange/replicationmessagepriority

http://schemas.microsoft.com/exchange/replicationschedule

http://schemas.microsoft.com/exchange/replicationstyle

DAV:searchrequest

DAV:searchtype

urn:schemas:httpmail:special

urn:schemas:httpmail:unreadcount

Expected Content Class

urn:content-classes:item

urn:content-classes:folder


urn:content-classes:freebusy

The urn:content-classes:freebusy content class defines a set of properties for an item that contains free/busy information.

Extends
urn:content-classes:item
COM Prog ID
CDO.Item

Properties

None

© 2000-2001 Microsoft Corporation. All rights reserved.


urn:content-classes:item

The urn:content-classes:item content class defines a set of properties for an item in the Web Storage System.

Extends
urn:content-classes:object
COM Prog ID
CDO.Item

Properties

http://schemas.microsoft.com/mapi/proptag/0x001A001F

DAV:abstract

DAV:autoversion

DAV:checkintime

DAV:childautoversioning

DAV:childcount

DAV:childversioning

DAV:comment

DAV:contentclass

http://schemas.microsoft.com/exchange/contentstate

http://schemas.microsoft.com/repl/contenttag

DAV:creationdate

DAV:defaultdocument

http://schemas.microsoft.com/exchange/defaultrevision

DAV:displayname

urn:schemas:httpmail:expiry-date

DAV:getcontentlanguage

DAV:getcontentlength

DAV:getcontenttype

DAV:getetag

DAV:getlastmodified

DAV:haschildren

DAV:hassubs

DAV:href

DAV:id

DAV:iscollection

DAV:isfolder

DAV:ishidden

DAV:isreadonly

DAV:isroot

DAV:isstructureddocument

DAV:isversioned

urn:schemas-microsoft-com:office:office#Keywords

DAV:lastaccessed

DAV:lockdiscovery

DAV:mergedfrom

http://schemas.microsoft.com/exchange/mid

http://schemas.microsoft.com/exchange/noaging

DAV:nosubs

http://schemas.microsoft.com/exchange/ntsecuritydescriptor

DAV:objectcount

DAV:parentname

http://schemas.microsoft.com/exchange/permanenturl

urn:schemas:httpmail:read

http://schemas.microsoft.com/repl/resourcetag

DAV:resourcetype

DAV:revisioncomment

DAV:revisionid

DAV:revisionlabel

DAV:revisionuri

DAV:supportedlock

http://schemas.microsoft.com/repl/uid

DAV:uid

DAV:visiblecount

DAV:vresourceid

© 2000-2001 Microsoft Corporation. All rights reserved.


urn:content-classes:journalfolder

The urn:content-classes:journalfolder content class defines a set of properties for a folder that primarily contains journal items.

Extends
urn:content-classes:folder
COM Prog ID
CDO.Folder

Expected Content Class

urn:content-classes:item

urn:content-classes:folder


urn:content-classes:mailfolder

The urn:content-classes:mailfolder content class defines a set of properties for a folder that primarily contains messages.

Extends
urn:content-classes:folder
COM Prog ID
CDO.Folder

Expected Content Class

urn:content-classes:message

urn:content-classes:calendarmessage


urn:content-classes:mdn

The urn:content-classes:mdn content class defines a set of properties for an item that is a mail delivery notification (MDN) message.

Extends
urn:content-classes:reportmessage
COM Prog ID
CDO.Message

Properties

None

© 2000-2001 Microsoft Corporation. All rights reserved.


urn:content-classes:message

The urn:content-classes:message content class defines a set of properties for an item that is a message.

Extends
urn:content-classes:item
COM Prog ID
CDO.Message

Properties

urn:schemas:mailheader:approved

urn:schemas:httpmail:attachmentfilename

urn:schemas:mailheader:bcc

urn:schemas:httpmail:bcc

urn:schemas:httpmail:cc

urn:schemas:mailheader:cc

urn:schemas:mailheader:comment

urn:schemas:mailheader:content-base

urn:schemas:mailheader:content-class

urn:schemas:mailheader:content-description

urn:schemas:mailheader:content-disposition

urn:schemas:httpmail:content-disposition-type

urn:schemas:mailheader:content-id

urn:schemas:mailheader:content-language

urn:schemas:mailheader:content-location

urn:schemas:httpmail:content-media-type

urn:schemas:mailheader:content-transfer-encoding

urn:schemas:mailheader:content-type

urn:schemas:mailheader:control

urn:schemas:httpmail:date

urn:schemas:mailheader:date

urn:schemas:httpmail:datereceived

urn:schemas:httpmail:displaycc

urn:schemas:httpmail:displayto

urn:schemas:mailheader:disposition

urn:schemas:mailheader:disposition-notification-to

urn:schemas:mailheader:distribution

urn:schemas:mailheader:expires

urn:schemas:mailheader:expiry-date

urn:schemas:httpmail:flagcompleted

urn:schemas:mailheader:followup-to

urn:schemas:httpmail:from

urn:schemas:mailheader:from

urn:schemas:httpmail:fromemail

urn:schemas:httpmail:fromname

urn:schemas:httpmail:hasattachment

urn:schemas:httpmail:htmldescription

urn:schemas:httpmail:importance

urn:schemas:mailheader:importance

urn:schemas:mailheader:in-reply-to

urn:schemas:mailheader:keywords

urn:schemas:mailheader:lines

urn:schemas:mailheader:message-id

urn:schemas:httpmail:messageflag

urn:schemas:mailheader:mime-version

urn:schemas:mailheader:newsgroups

urn:schemas:httpmail:normalizedsubject

urn:schemas:mailheader:organization

urn:schemas:mailheader:original-recipient

urn:schemas:mailheader:path

urn:schemas:mailheader:posting-version

urn:schemas:httpmail:priority

urn:schemas:mailheader:priority

urn:schemas:mailheader:received

urn:schemas:mailheader:references

urn:schemas:mailheader:relay-version

urn:schemas:httpmail:reply-by

urn:schemas:mailheader:reply-by

urn:schemas:httpmail:reply-to

urn:schemas:mailheader:reply-to

urn:schemas:mailheader:return-path

urn:schemas:mailheader:return-receipt-to

urn:schemas:httpmail:savedestination

urn:schemas:httpmail:saveinsent

urn:schemas:mailheader:sender

urn:schemas:httpmail:sender

urn:schemas:httpmail:senderemail

urn:schemas:httpmail:sendername

http://schemas.microsoft.com/exchange/sensitivity

urn:schemas:mailheader:sensitivity

urn:schemas:httpmail:subject

urn:schemas:mailheader:subject

urn:schemas:httpmail:submitted

urn:schemas:mailheader:summary

urn:schemas:httpmail:textdescription

urn:schemas:mailheader:thread-index

urn:schemas:mailheader:thread-topic

urn:schemas:httpmail:thread-topic

urn:schemas:httpmail:to

urn:schemas:mailheader:to

urn:schemas:mailheader:x-mailer

urn:schemas:mailheader:x-message-completed

urn:schemas:mailheader:x-message-flag

urn:schemas:mailheader:x-unsent

urn:schemas:mailheader:xref


urn:content-classes:notesfolder

The urn:content-classes:notesfolder content class defines a set of properties for a folder that primarily contains note items.

Extends
urn:content-classes:folder
COM Prog ID
CDO.Folder

Expected Content Class

urn:content-classes:item

urn:content-classes:folder


urn:content-classes:object

The urn:content-classes:object content class defines a property for a base object in the Web Storage System.

Extends
None
COM Prog ID
CDO.Item

Properties

urn:schemas-microsoft-com:exch-data:schema-collection-ref

Property Defaults

None

© 2000-2001 Microsoft Corporation. All rights reserved.


urn:content-classes:person

The urn:content-classes:person content class defines a set of properties for an item that is a contact.

Extends
urn:content-classes:item
COM Prog ID
CDO.Person

Properties

urn:schemas:contacts:account

urn:schemas:contacts:bday

urn:schemas:contacts:billinginformation

urn:schemas:contacts:businesshomepage

urn:schemas:contacts:c

urn:schemas:contacts:callbackphone

urn:schemas:contacts:children

urn:schemas:contacts:childrensnames

urn:schemas:contacts:cn

urn:schemas:contacts:co

http://schemas.microsoft.com/exchange/companies

urn:schemas:contacts:computernetworkname

urn:schemas:contacts:customerid

urn:schemas:contacts:department

urn:schemas:contacts:dn

urn:schemas:contacts:email1

urn:schemas:contacts:email2

urn:schemas:contacts:email3

urn:schemas:contacts:employeenumber

http://schemas.microsoft.com/exchange/extensionattribute1

http://schemas.microsoft.com/exchange/extensionattribute2

http://schemas.microsoft.com/exchange/extensionattribute3

http://schemas.microsoft.com/exchange/extensionattribute4

urn:schemas:contacts:facsimiletelephonenumber

urn:schemas:calendar:fburl

urn:schemas:contacts:fileas

urn:schemas:contacts:fileasid

urn:schemas:contacts:ftpsite

urn:schemas:contacts:gender

urn:schemas:calendar:geolatitude

urn:schemas:calendar:geolongitude

urn:schemas:contacts:givenName

urn:schemas:contacts:governmentid

urn:schemas:httpmail:hasattachment

urn:schemas:contacts:hobbies

urn:schemas:contacts:homeCity

urn:schemas:contacts:homeCountry

urn:schemas:contacts:homefax

urn:schemas:contacts:homelatitude

urn:schemas:contacts:homelongitude

urn:schemas:contacts:homePhone

urn:schemas:contacts:homephone2

urn:schemas:contacts:homepostaladdress

urn:schemas:contacts:homePostalCode

urn:schemas:contacts:homepostofficebox

urn:schemas:contacts:homeState

urn:schemas:contacts:homeStreet

urn:schemas:contacts:hometimezone

urn:schemas:httpmail:htmldescription

urn:schemas:contacts:initials

urn:schemas:contacts:internationalisdnnumber

urn:schemas:contacts:l

urn:schemas:contacts:language

urn:schemas:contacts:location

urn:schemas:contacts:mailingaddressid

urn:schemas:contacts:mailingcity

urn:schemas:contacts:mailingcountry

urn:schemas:contacts:mailingpostaladdress

urn:schemas:contacts:mailingpostalcode

urn:schemas:contacts:mailingpostofficebox

urn:schemas:contacts:mailingstate

urn:schemas:contacts:mailingstreet

urn:schemas:contacts:manager

urn:schemas:contacts:mapurl

urn:schemas:contacts:middlename

http://schemas.microsoft.com/exchange/mileage

urn:schemas:contacts:mobile

urn:schemas:contacts:namesuffix

urn:schemas:contacts:nickname

urn:schemas:contacts:o

urn:schemas:contacts:office2telephonenumber

urn:schemas:contacts:officetelephonenumber

urn:schemas:contacts:organizationmainphone

urn:schemas:contacts:othercity

urn:schemas:contacts:othercountry

urn:schemas:contacts:othercountrycode

urn:schemas:contacts:otherfax

urn:schemas:contacts:othermobile

urn:schemas:contacts:otherpager

urn:schemas:contacts:otherpostaladdress

urn:schemas:contacts:otherpostalcode

urn:schemas:contacts:otherpostofficebox

urn:schemas:contacts:otherstate

urn:schemas:contacts:otherstreet

urn:schemas:contacts:otherTelephone

urn:schemas:contacts:othertimezone

urn:schemas:httpmail:outbox

urn:schemas:contacts:pager

urn:schemas:contacts:personalHomePage

urn:schemas:contacts:personaltitle

urn:schemas:contacts:postalcode

urn:schemas:contacts:postofficebox

urn:schemas:contacts:profession

urn:schemas:contacts:proxyaddresses

urn:schemas:contacts:referredby

urn:schemas:contacts:roomnumber

http://schemas.microsoft.com/exchange/searchfolder

urn:schemas:contacts:secretarycn

urn:schemas:contacts:secretaryphone

urn:schemas:contacts:secretaryurl

urn:schemas:contacts:sn

urn:schemas:contacts:sourceurl

urn:schemas:contacts:spousecn

urn:schemas:contacts:st

urn:schemas:contacts:street

urn:schemas:mailheader:subject

urn:schemas:httpmail:subject

urn:schemas:contacts:telephoneNumber

urn:schemas:contacts:telephonenumber2

urn:schemas:contacts:telexnumber

urn:schemas:httpmail:textdescription

urn:schemas:contacts:title

urn:schemas:contacts:ttytddphone

urn:schemas:contacts:usercertificate

urn:schemas:contacts:weddinganniversary

urn:schemas:contacts:workaddress

http://schemas.microsoft.com/exchange/yomifirstname

http://schemas.microsoft.com/exchange/yomilastname

http://schemas.microsoft.com/exchange/yomiorganization


urn:content-classes:propertydef

The urn:content-classes:propertydef content class defines a set of properties for an item that defines a property for the Web Storage System schema.

Extends
urn:schemas-microsoft-com:xml-data#ElementType
COM Prog ID
CDO.Item

Properties

urn:schemas-microsoft-com:exch-data:default

urn:schemas-microsoft-com:exch-data:dictionary

urn:schemas-microsoft-com:exch-data:iscontentindexed

urn:schemas-microsoft-com:exch-data:isindexed

urn:schemas-microsoft-com:exch-data:ismultivalued

urn:schemas-microsoft-com:exch-data:isreadonly

urn:schemas-microsoft-com:exch-data:isrequired

urn:schemas-microsoft-com:exch-data:isvisible

urn:schemas-microsoft-com:exch-data:synchronize

urn:schemas-microsoft-com:datatypes#type

urn:schemas-microsoft-com:exch-data:version


urn:content-classes:propertyoverride

The urn:content-classes:propertyoverride defines a set of properties for overriding attributes on a property definition for a given content class.

Extends
urn:schemas-microsoft-com:xml-data#ElementType
COM Prog ID
CDO.Item

Properties

urn:schemas-microsoft-com:exch-data:default

urn:schemas-microsoft-com:exch-data:dictionary

urn:schemas-microsoft-com:exch-data:isrequired

urn:schemas-microsoft-com:exch-data:propertydef

urn:schemas-microsoft-com:exch-data:synchronize

urn:schemas-microsoft-com:exch-data:version


urn:content-classes:recallmessage

The urn:content-classes:recallmessage content class defines a set of properties for a recall message.

Extends
urn:content-classes:message
COM Prog ID
CDO.Message

Properties

None

© 2000-2001 Microsoft Corporation. All rights reserved.


urn:content-classes:recallreport

The urn:content-classes:recallreport content class defines a set of properties for an item that is a recall report message.

Extends
urn:content-classes:reportmessage
COM Prog ID
CDO.Message

Properties

None

© 2000-2001 Microsoft Corporation. All rights reserved.


urn:content-classes:taskfolder

The urn:content-classes:taskfolder content class defines a set of properties for a folder that primarily contains task items.

Extends
urn:content-classes:folder
COM Prog ID
CDO.Folder

Expected Content Class

urn:content-classes:item

urn:content-classes:folder


urn:schemas-microsoft-com:xml-data#ElementType

The urn:schemas-microsoft-com:xml-data content class defines a set of properties for schema definition items. This class is used as a base content class for schema definition items such as the urn:content-classes:contentclassdef and urn:content-classes:propertydef content classes.

Extends
urn:content-classes:item
COM Prog ID
CDO.Item

Properties

urn:schemas-microsoft-com:xml-data#extends

urn:schemas-microsoft-com:xml-data#name


Content Class Mappings from MAPI

The Microsoft® Web Storage System automatically calculates and returns a value for an item's DAV:contentclass property when the property is requested by a client using the WebDAV protocol or the Exchange OLE DB provider, if a value has not been explicitly set. In the case of a folder, the Web Storage System calculates a value using the item's PR_CONTAINER_CLASS property. In all other cases, the Web Storage System uses the item's PR_MESSAGE_CLASS property. This calculation occurs, for example, when a MAPI client such as Microsoft® Outlook® first creates an item in the Web Storage System and a client subsequently requests the DAV:contentclass property for the item using the WebDAV protocol or the Exchange OLE DB provider.

The following topics discuss the PR_MESSAGE_CLASS and PR_CONTAINER_CLASS properties and how they are mapped to a value for the item's DAV:contentclass property when necessary:

  • Mapping PR_CONTAINER_CLASS to DAV:contentclass
  • Mapping PR_MESSAGE_CLASS to DAV:contentclass

Note The value for an item's PR_CONTAINER_CLASS or PR_MESSAGE_CLASS can be accessed through the WebDAV protocol or the Exchange OLE DB provider using the http://schemas.microsoft.com/exchange/outlookfolderclass and http://schemas.microsoft.com/exchange/outlookmessageclass properties respectively.


Mapping PR_CONTAINER_CLASS to DAV:contentclass

When the item is a folder, the value of its PR_CONTAINER_CLASS is examined for a match in the following table, traversing the first column from top to bottom. The first match found is returned as the value for the item's DAV:contentclass property. The asterisk (*) wildcard character denotes any set of characters.

PR_CONTAINER_CLASS | Content Class
IPF | urn:content-classes:folder
IPF.Appointment | urn:content-classes:calendarfolder
IPF.Contact | urn:content-classes:contactfolder
IPF.Journal | urn:content-classes:journalfolder
IPF.Note | urn:content-classes:mailfolder
IPF.StickyNote | urn:content-classes:notefolder
IPF.Task | urn:content-classes:taskfolder
IPF.* (Folder under Inbox) | urn:content-classes:mailfolder
IPF.* (All others) | urn:content-classes:folder


Mapping PR_MESSAGE_CLASS to DAV:contentclass

When the item is not a folder, the value of its PR_MESSAGE_CLASS property is examined for a match in the following tables, traversing the first column from top to bottom. The first match found is returned as the value for the item's DAV:contentclass property. The asterisk (*) wildcard character denotes any set of characters. The dollar-sign ($) character denotes the end of the string. All other strings must be matched exactly. The tables are broken down into three categories: values with the prefix IPC, IPM, and REPORT. All values not resolved in one of the three tables map to the value "urn:content-classes:document".

IPC
PR_MESSAGE_CLASS | Content Class
IPC | urn:content-classes:document
IPC.* | urn:content-classes:document

IPM
PR_MESSAGE_CLASS | Content Class
IPM | urn:content-classes:document
IPM.Activity | urn:content-classes:activity
IPM.Appointment | urn:content-classes:appointment
IPM.Conflict.Resolution.Message | http://content-classes.microsoft.com/exchange/conflict
IPM.Contact | urn:content-classes:person
IPM.ContentClassDef | urn:content-classes:contentclassdef
IPM.DistList | urn:content-classes:group
IPM.Document | urn:content-classes:document
IPM.Document.*doc | urn:content-classes:document
IPM.Document.Excel.Sheet.5 | urn:content-classes:document
IPM.Document.Excel.Sheet.8 | urn:content-classes:document
IPM.Document.Microsoft Internet Mail Message | urn:content-classes:message
IPM.Document.MSProject.Project.4_1 | urn:content-classes:document
IPM.Document.MSProject.Project.8 | urn:content-classes:document
IPM.Document.PowerPoint.Show.4 | urn:content-classes:document
IPM.Document.PowerPoint.Show.7 | urn:content-classes:document
IPM.Document.PowerPoint.Show.8 | urn:content-classes:document
IPM.Document.textfile | urn:content-classes:document
IPM.Document.Word.Document.6 | urn:content-classes:document
IPM.Document.Word.Document.8 | urn:content-classes:document
IPM.Microsoft.KeyExchange | http://content-classes.microsoft.com/exchange/keyexchange
IPM.Microsoft.ScheduleData.FreeBusy | urn:content-classes:freebusy
IPM.Note | urn:content-classes:message
IPM.Note.Exchange.Security.Enrollment | urn:content-classes:message
IPM.Note.IMC.Notification | urn:content-classes:message
IPM.Note.P772 | urn:content-classes:message
IPM.Note.RFC822.MIME | urn:content-classes:message
IPM.Note.Rules.OofTemplate.Microsoft | urn:content-classes:message
IPM.Note.Rules.ReplyTemplate.Microsoft | urn:content-classes:message
IPM.Note.Secure | urn:content-classes:message
IPM.Note.Secure.Service.Reply | urn:content-classes:message
IPM.Note.Secure.Sign | urn:content-classes:message
IPM.Note.SMIME | urn:content-classes:message
IPM.Note.SMIME.MultipartSigned | urn:content-classes:message
IPM.Note.StorageQuotaWarning | urn:content-classes:message
IPM.Object | urn:content-classes:object
IPM.Organization | urn:content-classes:organization
IPM.Outlook.Recall | urn:content-classes:recallmessage
IPM.Post | urn:content-classes:message
IPM.PropertyDef | urn:content-classes:propertydef
IPM.Recall.Report | urn:content-classes:recallreport
IPM.Recall.Report.Failure | urn:content-classes:recallreport
IPM.Recall.Report.Success | urn:content-classes:recallreport
IPM.Report | urn:content-classes:reportmessage
IPM.Schedule.Meeting.Canceled | urn:content-classes:calendarmessage
IPM.Schedule.Meeting.Request | urn:content-classes:calendarmessage
IPM.Schedule.Meeting.Resp.Neg | urn:content-classes:calendarmessage
IPM.Schedule.Meeting.Resp.Pos | urn:content-classes:calendarmessage
IPM.Schedule.Meeting.Resp.Tent | urn:content-classes:calendarmessage
IPM.StickyNote | urn:content-classes:note
IPM.Task | urn:content-classes:task
IPM.TaskRequest | urn:content-classes:calendarmessage
IPM.TaskRequest.Accept | urn:content-classes:calendarmessage
IPM.TaskRequest.Decline | urn:content-classes:calendarmessage
IPM.TaskRequest.Update | urn:content-classes:calendarmessage
IPM.Appointment.* | urn:content-classes:appointment
IPM.Schedule.Meeting.* | urn:content-classes:calendarmessage
IPM.Contact.* | urn:content-classes:person
IPM.Note.* | urn:content-classes:message
IPM.Document.* | urn:content-classes:document
IPM.* | urn:content-classes:message

REPORT
PR_MESSAGE_CLASS | Content Class
Report | urn:content-classes:reportmessage
Report.IPM.Note.DR | urn:content-classes:dsn
Report.IPM.Note.IPNNDR | urn:content-classes:mdn
Report.IPM.Note.IPNNRN | urn:content-classes:mdn
Report.IPM.Note.IPNRN | urn:content-classes:mdn
Report.IPM.Note.NDR | urn:content-classes:dsn
Report.IPM.Recall.Report.Failure.NDR | urn:content-classes:dsn
Report.IPM.Schedule.Meeting.Canceled.NDR | urn:content-classes:dsn
Report.IPM.Schedule.Meeting.Request.DR | urn:content-classes:dsn
Report.IPM.Schedule.Meeting.Request.IPNNRN | urn:content-classes:mdn
Report.IPM.Schedule.Meeting.Request.IPNRN | urn:content-classes:mdn
Report.IPM.Schedule.Meeting.Request.NDR | urn:content-classes:dsn
Report.IPM.Schedule.Meeting.Resp.Neg.NDR | urn:content-classes:dsn
Report.IPM.Schedule.Meeting.Resp.Pos.NDR | urn:content-classes:dsn
Report.IPM.Schedule.Meeting.Resp.Tent.NDR | urn:content-classes:dsn
Report.IPM.TaskRequest.Accept.NDR | urn:content-classes:dsn
Report.IPM.TaskRequest.Decline.NDR | urn:content-classes:dsn
Report.IPM.TaskRequest.NDR | urn:content-classes:dsn
Report.IPM.TaskRequest.Update.NDR | urn:content-classes:dsn
REPORT.*.DR$ | urn:content-classes:dsn
REPORT.*.IPNNDR$ | urn:content-classes:mdn
REPORT.*.IPNNRN$ | urn:content-classes:mdn
REPORT.*.IPNRN$ | urn:content-classes:mdn
REPORT.*.NDR$ | urn:content-classes:dsn
REPORT.* | urn:content-classes:message

All Other Values

All other values in PR_MESSAGE_CLASS map to the DAV:contentclass value "urn:content-classes:document".


Properties by Namespace

A namespace provides a unique name for every property in the Web Storage System Schema. For example, the namespaces urn:schemas:httpmail: and urn:schemas:mailheader: both contain properties named From. By prefacing the name of a property with the correct namespace, you can avoid collisions between properties with similar names. This section lists Web Storage System Schema properties that belong to each namespace.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


DAV: Namespace

Platform SDK: Exchange 2000 Server

DAV:Namespace

This namespaces defines properties for the Web-based Distributed Authoring and Versioning (WebDAV) protocol, including properties for general data access (such as DAV:href) and for determining hierarchical information such as DAV:isfolder.


abstract Field

A summary of Web Storage System item’s content. This property is used by Microsoft Outlook for preview displays.

Full Name

DAV:abstract

Content Class

urn:content:classes:item

Named Constant

CdoNSDAV.cdoAbstract

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

© 2000-2001 Microsoft Corporation. All rights reserved.


autoversion Field

Read-only. Specifies whether the resource is versioned automatically.

Full Name

DAV:autoversion

Content Class

urn:content:classes:item

OLE DB Type

DBTYPE_BOOL

Variant Subtype

[Visual Basic] Boolean

[C++] VARIANT_BOOL

© 2000-2001 Microsoft Corporation. All rights reserved.


checkintime Field

Read-only. A timestamp set by the server indicating when a report resource was checked in.

Full Name

DAV:checkintime

Content Class

urn:content:classes:item

OLE DB Type

DBTYPE_FILETIME

Variant Subtype

[Visual Basic] DateTime

[C++] VT_DATE

Example

3/29/1999 1:30:00 PM

© 2000-2001 Microsoft Corporation. All rights reserved.


childautoversioning Field

Automatically updates versioning for child items provided childversioning is TRUE.

Full Name

DAV:childautoversioning

Content Class

urn:content:classes:item

OLE DB Type

DBTYPE_BOOL

Variant Subtype

[Visual Basic] String

[C++] BSTR

© 2000-2001 Microsoft Corporation. All rights reserved.


childcount Field

Read-Only. A folder’s total number of items including subfolders.

Full Name

DAV:childcount

Content Class

urn:content:classes:item

Named Constant

CdoNSDAV.cdoChildCount

OLE DB Type

DBTYPE_I4

Variant Subtype

[Visual Basic] Long

[C++] long

Example

14


childversioning Field

Read-only. Specifies whether versioning is set a folder’s items and subfolders.

Full Name

DAV:childversioning

Content Class

urn:content:classes:item

OLE DB Type

DBTYPE_BOOL

Variant Subtype

[Visual Basic] bool

[C++] VARIANT_BOOL

See Also

childautoversioning


comment Field

A comment for the item.

Full Name

DAV:comment

Content Class

urn:content:classes:item

Named Constant

CdoNSDAV.cdoDAVComment

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Example

This is the latest document.


contentclass Field

The item's content class.

Full Name

DAV:contentclass

Content Class

urn:content:classes:item

urn:content:classes:object

Named Constant

CdoNSDAV.cdoContentClass

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Example

urn:content-classes:message


creationdate Field

Read-only. The date the item was created.

Full Name

DAV:creationdate

Content Class

urn:content:classes:item

Named Constant

CdoNSDAV.cdoCreationDate

OLE DB Type

DBTYPE_DBTIMESTAMP

Variant Subtype

[Visual Basic] DATE

[C++] VT_DATE

Example

3/29/1999 1:30:00 PM

© 2000-2001 Microsoft Corporation. All rights reserved.


defaultdocument Field

The name of an item that automatically displays when the folder is accessed by an application.

Full Name

DAV:defaultdocument

Content Class

urn:content:classes:item

Named Constant

CdoNSDAV.cdoDefaultDocument

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Remarks

Registering a form overrides the property’s setting.

Example

default.htm


displayname Field

Read-Only. A calculated field that can contain either the subject of a message or the urn:schemas:contact:fileas value for a contact. It also can contain an XML language attribute.

Full Name

DAV:displayname

Content Class

urn:content:classes:item

Named Constant

CdoNSDAV.cdoDisplayName

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Example

Pizza served on third floor lobby

© 2000-2001 Microsoft Corporation. All rights reserved.


getcontentlanguage Field

Read-only. The language header intended for use when you need to indicate the language(s) of an item that has RFC 822 headers, such as MIME-formatted message body parts or Web documents.

Full Name

DAV:getcontentlanguage

Content Class

urn:content:classes:item

Named Constant

CdoNSDAV.cdoGetContentLanguage

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Example

de


getcontentlength Field

Read-only. The size in bytes of an item.

Full Name

DAV:getcontentlength

Content Class

urn:content:classes:item

Named Constant

CdoNSDAV.cdoGetContentLength

OLE DB Type

DBTYPE_I4

Variant Subtype

[Visual Basic] Long

[C++] long

Example

452


getcontenttype Field

Read-only. The content type for the item.

Full Name

DAV:getcontenttype

Content Class

urn:content:classes:item

Named Constant

CdoNSDAV.cdoGetContentType

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Remarks

This property corresponds to the Content-Type MIME header field.

Example

image/gif


getetag Field

Read-only. The entity tag associated with a cached entry.

Full Name

DAV:getetag

Content Class

urn:content:classes:item

Named Constant

CdoNSDAV.cdoGetETag

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Example

customer


getlastmodified Field

Read-only. The time an item was last modified.

Full Name

DAV:getlastmodified

Content Class

urn:content:classes:item

Named Constant

CdoNSDAV.cdoGetLastModified

OLE DB Type

DBTYPE_DBTIMESTAMP

Variant Subtype

[Visual Basic] DATE

[C++] VT_DATE

Example

3/29/1999 1:30:00 PM

© 2000-2001 Microsoft Corporation. All rights reserved.


haschildren Field

Read-only. Indicates whether the folder or structured document item has child objects.

Full Name

DAV:haschildren

Content Class

urn:content:classes:item

Named Constant

CdoNSDAV.cdoHasChildren

OLE DB Type

DBTYPE_BOOL

Variant Subtype

[Visual Basic] Boolean

[C++] VARIANT_BOOL

Remarks

This property does not apply to items that are not collections.

Example

TRUE

© 2000-2001 Microsoft Corporation. All rights reserved.


hassubs Field

Read-Only. Indicates whether the folder item has subfolders.

Full Name

DAV:hassubs

Content Class

urn:content:classes:item

Named Constant

CdoNSDAV.cdoHasSubs

OLE DB Type

DBTYPE_BOOL

Variant Subtype

[Visual Basic] Boolean

[C++] VARIANT_BOOL

Remarks

Does not apply to structured documents.

Example

TRUE

See Also

DAV:haschildren

© 2000-2001 Microsoft Corporation. All rights reserved.


href Field

Read-only. The absolute uniform resource locator (URL) of an item.

Full Name

DAV:href

Content Class

urn:content:classes:item

Named Constant

CdoNSDAV.cdoHref

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Example

file://./backofficestorage/domain.tld/public folders/folder1/item.doc


id Field

Read-only. An item’s unique identifier.

Full Name

DAV:id

Content Class

urn:content:classes:item

Named Constant

CdoNSDAV.cdoID

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Example

AQEAAAAAAH0YAQAAAAAAfmoAAAAA

See Also

DAV:uid

© 2000-2001 Microsoft Corporation. All rights reserved.


iscollection Field

Read-only. Indicates whether or not the item is a collection.

Full Name

DAV:iscollection

Content Class

urn:content:classes:item

Named Constant

CdoNSDAV.cdoIsCollection

OLE DB Type

DBTYPE_BOOL

Variant Subtype

[Visual Basic] Boolean

[C++] VARIANT_BOOL

Remarks

Both structured documents and folders are collection items.

Example

TRUE

© 2000-2001 Microsoft Corporation. All rights reserved.


isfolder Field

Read-only. Indicates whether the item is a folder.

Full Name

DAV:isfolder

Content Class

urn:content:classes:item

Named Constant

CdoNSDAV.cdoIsFolder

OLE DB Type

DBTYPE_BOOL

Variant Subtype

[Visual Basic] Boolean

[C++] VARIANT_BOOL

Remarks

In the Web Storage System architecture, a folder is an item that is also a collection of other items.

Example

True

© 2000-2001 Microsoft Corporation. All rights reserved.


ishidden Field

Indicates whether the item is designated as hidden.

Full Name

DAV:ishidden

Content Class

urn:content:classes:item

Named Constant

CdoNSDAV.cdoIsHidden

OLE DB Type

DBTYPE_BOOL

Variant Subtype

[Visual Basic] Boolean

[C++] VARIANT_BOOL

Remarks

This property only has the intended result when the item is created in the Microsoft® Web Storage System, before calling the ADO Fields Update method. You cannot use DAV:IsHidden to toggle an existing item between being hidden and not hidden.

Example

TRUE

© 2000-2001 Microsoft Corporation. All rights reserved.


isreadonly Field

Indicates whether the item cannot be modified or deleted.

Full Name

DAV:isreadonly

Content Class

urn:content:classes:item

OLE DB Type

DBTYPE_BOOL

Variant Subtype

[Visual Basic] Boolean

[C++] VARIANT_BOOL

Example

TRUE

© 2000-2001 Microsoft Corporation. All rights reserved.


isroot Field

Indicates whether the item is a root folder.

Full Name

DAV:isroot

Content Class

urn:content:classes:item

Named Constant

CdoNSDAV.cdoIsroot

OLE DB Type

DBTYPE_BOOL

Variant Subtype

[Visual Basic] Boolean

[C++] VARIANT_BOOL

Example

FALSE

© 2000-2001 Microsoft Corporation. All rights reserved.


isstructureddocument Field

Read-only. Indicates whether the item is a structured document.

Full Name

DAV:isstructureddocument

Content Class

urn:content:classes:item

Named Constant

CdoNSDAV.cdoIsstructureddocument

OLE DB Type

DBTYPE_BOOL

Variant Subtype

[Visual Basic] Boolean

[C++] VARIANT_BOOL

Remarks

A structured document is one type of collection item.

Example

TRUE

© 2000-2001 Microsoft Corporation. All rights reserved.


isversioned Field

Read-only. Indicates whether the item is currently being versioned.

Full Name

DAV:isversioned

Content Class

urn:content:classes:item

OLE DB Type

DBTYPE_BOOL

Variant Subtype

[Visual Basic] Boolean

[C++] VARIANT_BOOL

Example

FALSE

© 2000-2001 Microsoft Corporation. All rights reserved.


lastaccessed Field

Read-only. The date and time the item was last accessed.

Full Name

DAV:lastaccessed

Content Class

urn:content:classes:item

Named Constant

CdoNSDAV.cdoLastaccessed

OLE DB Type

DBTYPE_DBTIMESTAMP

Variant Subtype

[Visual Basic] DATE

[C++] VT_DATE

Example

3/29/1999 1:30:00 PM

© 2000-2001 Microsoft Corporation. All rights reserved.


lockdiscovery Field

Read-only. The list of current locks on an item.

Full Name

DAV:lockdiscovery

Content Class

urn:content:classes:item

Named Constant

CdoNSDAV.cdoLockdiscovery

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Remarks

You cannot search for this property because its value is only calculated when used and is not persisted in the Web Storage System.

Example

<D:activelock>

<D:locktype><D:write/></D:locktype>

<D:lockscope><D:exclusive/></D:lockscope>

<D:depth>Infinity</D:depth>

<D:owner>domain\user</D:owner>

<D:href>http://server/user/inbox/msg1.eml</D:href>

</D:activelock>

© 2000-2001 Microsoft Corporation. All rights reserved.


mergedfrom Field

Any text for a client application to indicate a revision based on previous revisions.

Full Name

DAV:mergedfrom

Content Class

urn:content:classes:item

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Remarks

Might contan a list of revision Ids and how a merge was done.


nosubs Field

Read-only. Indicates whether subfolders can be created in this folder.

Full Name

DAV:nosubs

Content Class

urn:content:classes:item

Named Constant

CdoNSDAV.cdoNosubs

OLE DB Type

DBTYPE_BOOL

Variant Subtype

[Visual Basic] Boolean

[C++] VARIANT_BOOL

Remarks

This property only applies to the creation of subfolders, not structured documents.

Example

True

© 2000-2001 Microsoft Corporation. All rights reserved.


objectcount Field

Read-only. The number of items in a folder that are not folders.

Full Name

DAV:objectcount

Content Class

urn:content:classes:item

Named Constant

CdoNSDAV.cdoObjectcount

OLE DB Type

DBTYPE_I4

Variant Subtype

[Visual Basic] Long

[C++] long

Remarks

The count includes hidden objects in the folder.

Example

23

See Also

DAV:visiblecount

© 2000-2001 Microsoft Corporation. All rights reserved.


parentname Field

The name of the folder that contains the item.

Full Name

DAV:parentname

Content Class

urn:content:classes:item

Named Constant

CdoNSDAV.cdoParentname

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Example

Reports

© 2000-2001 Microsoft Corporation. All rights reserved.


resourcetype Field

Read-only. Indicates the item type.

Full Name

DAV:resourcetype

Content Class

urn:content:classes:item

Named Constant

CdoNSDAV.cdoResourcetype

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Remarks

The value is either <collection/> or empty. The former indicates that the item is a collection. The latter indicates that it is not a collection.

You cannot search for this property because its value is only calculated when used and is not persisted in the Web Storage System.

Example

<collection/>

© 2000-2001 Microsoft Corporation. All rights reserved.


revisioncomment Field

A comment for a particular version of an item.

Full Name

DAV:revisioncomment

Content Class

urn:content:classes:item

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Example

Fixed the abstract of the document.


revisionid Field

Read-only. The unique identifier of the item version.

Full Name

DAV:revisionid

Content Class

urn:content:classes:item

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Example

32


revisionlabel Field

A label for a particular version of an item.

Full Name

DAV:revisionlabel

Content Class

urn:content:classes:item

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Remarks

Use labels to allow easy distinction between versions of an item.

Example

Draft 8

© 2000-2001 Microsoft Corporation. All rights reserved.


revisionuri Field

Reserved for future use.

Full Name

DAV:revisionuri

Content Class

urn:content:classes:item

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

© 2000-2001 Microsoft Corporation. All rights reserved.


searchrequest Field

Read-only. The original query used to build the search folder.

Full Name

DAV:searchrequest

Content Classes

urn:content-classes:folder

urn:content:classes:item

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Remarks

You cannot search for this property because its value is only calculated when used and is not persisted in the Web Storage System.

Example

select * from scope('deep traversal of "someurl"') where contains("DAV:comment","Microsoft")


searchtype Field

Read-only. The server sets this property as either static or dynamic for client applications to determine whether or not a search folder will change.

Full Name

DAV:searchtype

Content Class

urn:content-classes:folder

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

© 2000-2001 Microsoft Corporation. All rights reserved.


supportedlock Field

Read-only. This field contains an XML file of nodes describing lock conditions for the item. This field can be accessed using HTTP 1.1 extensions and WebDAV.

Full Name

DAV:supportedlock

Content Class

urn:content:classes:item

Named Constant

CdoNSDAV.cdoSupportedlock

OLE DB Type

DBTYPE_VECTOR WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Remarks

This field contains an XML hierarchy describing lock conditions for the item. The XML cannot be manipulated using OLE DB or ADO. Although its data type in the Web Storage System is a multivalued string (PT_MV_UNICODE), this field is persisted as an XML file with no other accompanying strings.


uid Field

Read-only. A unique identifier for the item.

Full Name

DAV:uid

Content Class

urn:content:classes:item

Named Constant

CdoNSDAV.cdoUid

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Example

AQEAAAAAAH5rAAAAAAAAAAAAAAAA

See Also

DAV:id

© 2000-2001 Microsoft Corporation. All rights reserved.


visiblecount Field

Read-only. The number of visible items in a folder that are not folders.

Full Name

DAV:visiblecount

Content Class

urn:content:classes:item

Named Constant

CdoNSDAV.cdoVisiblecount

OLE DB Type

DBTYPE_I4

Variant Subtype

[Visual Basic] String

[C++] BSTR

Remarks

Items in a folder that have DAV:isfolder and DAV:ishidden set to true do not show up in the visible count tally.

Example

123


vresourceid Field

Read-only. A unique identifier for an item that is being versioned.

Full Name

DAV:vresourceid

Content Class

urn:content:classes:item

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Remarks

All versions of an item that is under revision control have the same identifier.

The Web Storage System sets this identifier and it cannot be changed.

Example

3FMVjKpVtkKfJjzbFAZNwQAAAAB+ag==

© 2000-2001 Microsoft Corporation. All rights reserved.


http://schemas.microsoft.com/exchange/ Namespace

The http://schemas.microsoft.com/exchange namespace contains properties that are primarily Microsoft® Exchange 2000 Server-specific and are not related directly to Internet standards.


addressbookdisplayname Field

Platform SDK: Exchange 2000 Server

addressbookdisplayname

The name for a Web Storage System folder in Active Directory. This field is in the CDO Folder object’s field collection.

Full Name

http://schemas.microsoft.com/exchange/addressbookdisplayname

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

© 2000-2001 Microsoft Corporation. All rights reserved.


adminfolderdescription Field

A description of the public folder normally provided by the Microsoft Exchange 2000 Server administrator.

Full Name

http://schemas.microsoft.com/exchange/adminfolderdescription

Content Class

urn:content-classes:folder

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

© 2000-2001 Microsoft Corporation. All rights reserved.


eld

Platform SDK: Exchange 2000 Server

alias Field

A person’s e-mail alias.

Full Name

http://schemas.microsoft.com/exchange/alias

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Remarks

This field is also available as the IEmailRecipient::Alias.

Example

BrianF could be an alias for Brian Fleming.


pient Field

Platform SDK: Exchange 2000 Server

altrecipient Field

An alternative recipient to receive e-mail.

Full Name

http://schemas.microsoft.com/exchange/altrecipient

Named Constant

CDOAltRecipient

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

© 2000-2001 Microsoft Corporation. All rights reserved.


archive Field

Indicates whether the item has changed and needs to be archived. An archive application sets this field to FALSE upon completion.

Full Name

http://schemas.microsoft.com/exchange/archive

OLE DB Type

DBTYPE_BOOL

Variant Subtype

[Visual Basic] Boolean

[C++] VARIANT_BOOL

© 2000-2001 Microsoft Corporation. All rights reserved.


companies Field

A multi-valued property used by Microsoft® Outlook to list one or more companies associated with Web Storage System content.

Full Name

http://schemas.microsoft.com/exchange/companies

Content Class

urn:content-classes:person

urn:content-classes:appointment

Named Constant

cdoCompanies

OLE DB Type

VECTOR WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Example

Microsoft Trey Research

© 2000-2001 Microsoft Corporation. All rights reserved.


contentexpiryagelimit Field

The expiry age limit in days for items in public folders.

Full Name

http://schemas.microsoft.com/exchange/contentexpiryagelimit

Content Class

urn:content-classes:folder

OLE DB Type

DBTYPE_I4

Variant Subtype

[Visual Basic] Long

[C++] long

Example

30


contentstate Field

Any text that describes the state, or status, of an item.

Full Name

http://schemas.microsoft.com/exchange/contentstate

Content Class

urn:content:classes:item

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Example

Sold

© 2000-2001 Microsoft Corporation. All rights reserved.


defaultrevision Field

Read-only. A default revision identifier.

Full Name

http://schemas.microsoft.com/exchange/defaultrevision

Content Class

urn:content:classes:item

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

© 2000-2001 Microsoft Corporation. All rights reserved.


deleteditemflags Field

The number of items in the deleted items folder.

Full Name

http://schemas.microsoft.com/exchange/deleteditemflags

OLE DB Type

DBTYPE_I4

Variant Subtype

[Visual Basic] Long

[C++] long

Example

23


deleteditemsagelimit Field

Number of days, on a per-folder basis, to retain deleted items.

Full Name

http://schemas.microsoft.com/exchange/deleteditemsagelimit

Content Class

urn:content-classes:folder

OLE DB Type

DBTYPE_I4

Variant Subtype

[Visual Basic] Long

[C++] long

Example

30


delivcontlength Field

Amount of data, in kilobytes (KB), that you are allowed to receive.

Full Name

http://schemas.microsoft.com/exchange/delivcontlength

OLE DB Type

DBTYPE_UI4

Variant Subtype

[Visual Basic] Integer

[C++] unsigned int

© 2000-2001 Microsoft Corporation. All rights reserved.


deliverandredirect Field

Indicates whether to forward every message to another recipient.

Full Name

http://schemas.microsoft.com/exchange/deliverandredirect

OLE DB Type

DBTYPE_BOOL

Variant Subtype

[Visual Basic] Boolean

[C++] VARIANT_BOOL

© 2000-2001 Microsoft Corporation. All rights reserved.


disableperuserread Field

Indicates whether read processing is disabled on a per-user basis. If TRUE, per-user read processing is disabled.

Full Name

http://schemas.microsoft.com/exchange/disableperuserread

OLE DB Type

DBTYPE_BOOL

Variant Subtype

[Visual Basic] Boolean

[C++] VARIANT_BOOL

Example

TRUE

© 2000-2001 Microsoft Corporation. All rights reserved.


extensionattribute1 Field

An attribute for any text without having to extend Active Directory.

Full Name

http://schemas.microsoft.com/exchange/extensionattribute1

Content Class

urn:content-classes:person

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

© 2000-2001 Microsoft Corporation. All rights reserved.


extensionattribute2 Field

An attribute for any text without having to extend Active Directory.

Full Name

http://schemas.microsoft.com/exchange/extensionattribute2

Content Class

urn:content-classes:person

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

© 2000-2001 Microsoft Corporation. All rights reserved.


extensionattribute3 Field

An attribute for any text without having to extend Active Directory.

Full Name

http://schemas.microsoft.com/exchange/extensionattribute3

Content Class

urn:content-classes:person

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

© 2000-2001 Microsoft Corporation. All rights reserved.


extensionattribute4 Field

An attribute for any text without having to extend Active Directory.

Full Name

http://schemas.microsoft.com/exchange/extensionattribute4

Content Class

urn:content-classes:person

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

© 2000-2001 Microsoft Corporation. All rights reserved.


extensionattribute5 Field

An attribute for any text without having to extend Active Directory.

Full Name

http://schemas.microsoft.com/exchange/extensionattribute5

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

© 2000-2001 Microsoft Corporation. All rights reserved.


extensionattribute6 Field

An attribute for any text without having to extend Active Directory.

Full Name

http://schemas.microsoft.com/exchange/extensionattribute6

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

© 2000-2001 Microsoft Corporation. All rights reserved.


extensionattribute7 Field

An attribute for any text without having to extend Active Directory.

Full Name

http://schemas.microsoft.com/exchange/extensionattribute7

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

© 2000-2001 Microsoft Corporation. All rights reserved.


extensionattribute8 Field

An attribute for any text without having to extend Active Directory.

Full Name

http://schemas.microsoft.com/exchange/extensionattribute8

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

© 2000-2001 Microsoft Corporation. All rights reserved.


extensionattribute9 Field

An attribute for any text without having to extend Active Directory.

Full Name

http://schemas.microsoft.com/exchange/extensionattribute9

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

© 2000-2001 Microsoft Corporation. All rights reserved.


extensionattribute10 Field

An attribute for any text without having to extend Active Directory.

Full Name

http://schemas.microsoft.com/exchange/extensionattribute10

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

© 2000-2001 Microsoft Corporation. All rights reserved.


foldersize Field

Read-only. The total size, in bytes, of all of the items in a folder.

Full Name

http://schemas.microsoft.com/exchange/foldersize

Content Class

urn:content-classes:folder

Named Constant

cdoFolderSize

OLE DB Type

DBTYPE_I4

Variant Subtype

[Visual Basic] Long

[C++] long

Example

23


freebusypublishamount Field

Determines the number of months publish free/busy information for a user. The default is three months.

Full Name

http://schemas.microsoft.com/exchange/freebusypublishamount

OLE DB Type

DBTYPE_UI4

Variant Subtype

[Visual Basic] Ingeger

[C++] unsigned int

Example

3


hardlinklist Field

A list of folder URLs in which to post a message.

Full Name

http://schemas.microsoft.com/exchange/hardlinklist

OLE DB Type

DBTYPE_ARRAY | DBTYPE_VARIANT

Variant Subtype

String()

Remarks

You put the hardlinklist property into a Message object's Configuration object to specify in which folder to post a message.

Currently only one folder can be specified using the hardlinklist property.


homemdb Field

The URL to the recipient’s store.

Full Name

http://schemas.microsoft.com/exchange/homemdb

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Remarks

This field is also available as the IMailBoxStore:Homemdb property.


longdateformat Field

Format for long dates in Outlook Web Access.

Full Name

http://schemas.microsoft.com/exchange/longdateformat

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

© 2000-2001 Microsoft Corporation. All rights reserved.


mdboverhardquotalimit Field

The maximum mailbox size, in KB, over which sending and receiving mail is disabled.

Full Name

http://schemas.microsoft.com/exchange/mdboverhardquotalimit

OLE DB Type

DBTYPE_I4

Variant Subtype

[Visual Basic] Long

[C++] long

Remarks

This field is also available as the IMailBoxStore:Hardlimit property.


mdboverquotalimit Field

The mailbox quota overdraft limit in Kilobytes (KB).

Full Name

http://schemas.microsoft.com/exchange/mdboverquotalimit

OLE DB Type

DBTYPE_I4

Variant Subtype

[Visual Basic] Long

[C++] long

© 2000-2001 Microsoft Corporation. All rights reserved.


mdbstoragequota Field

The MDB quota in Kilobytes (KB).

Full Name

http://schemas.microsoft.com/exchange/mdbstoragequota

OLE DB Type

DBTYPE_UI4

Variant Subtype

[Visual Basic] Long

[C++] long

© 2000-2001 Microsoft Corporation. All rights reserved.


mdbusedefaults Field

Indicates whether the store should use the default quota, rather than the per-mailbox quota.

Full Name

http://schemas.microsoft.com/exchange/mdbusedefaults

OLE DB Type

DBTYPE_BOOL

Variant Subtype

[Visual Basic] Boolean

[C++] VARIANT_BOOL

© 2000-2001 Microsoft Corporation. All rights reserved.


mid Field

Read-only. Reserved for Future Use.

Full Name

http://schemas.microsoft.com/exchange/mid

Content Class

urn:content:classes:item

OLE DB Type

DBTYPE_I8

Variant Subtype

[Visual Basic] Long

[C++] long

Example

23


mileage Field

Used for Microsoft® Outlook® interoperability.

Full Name

http://schemas.microsoft.com/exchange/mileage

Content Class

urn:content-classes:person

urn:content-classes:appointment

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

© 2000-2001 Microsoft Corporation. All rights reserved.


noaging Field

Used for Microsoft® Outlook® interoperability.

Full Name

http://schemas.microsoft.com/exchange/noaging

Content Class

urn:content:classes:item

OLE DB Type

DBTYPE_BOOL

Variant Subtype

[Visual Basic] Boolean

[C++] VARIANT_BOOL

© 2000-2001 Microsoft Corporation. All rights reserved.


ntsecuritydescriptor Field

This binary property contains the security descriptor for the item. The security descriptor contains the item's primary owner and group, and a discretionary access control list granting and denying various rights to particular users and groups. The Microsoft® Win32® API provides numerous functions that can be used to manipulate the security descriptor; applications must not manipulate the security descriptor directly.

Full Name

http://schemas.microsoft.com/exchange/ntsecuritydescriptor

Content Class

urn:content:classes:item

OLE DB Type

DBTYPE_BYTES

Variant Subtype

Not supported.


originaldate Field

Original date a message was sent when returned in a report. Used for Web client reports.

Full Name

http://schemas.microsoft.com/exchange/originaldate

OLE DB Type

DBTYPE_DATE

Variant Subtype

[Visual Basic] Date

[C++] VT_DATE

© 2000-2001 Microsoft Corporation. All rights reserved.


originaldisplaybcc Field

The original bcc list of a message referred to in a report.

Full Name

http://schemas.microsoft.com/exchange/originaldisplaybcc

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

© 2000-2001 Microsoft Corporation. All rights reserved.


originaldisplaycc Field

Used in reports for in Outlook Web Access, shows the original cc list of a message.

Full Name

http://schemas.microsoft.com/exchange/originaldisplaycc

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

© 2000-2001 Microsoft Corporation. All rights reserved.


originaldisplayto Field

Used in reports for in Outlook Web Access, shows the display names for the original bcc list on a report.

Full Name

http://schemas.microsoft.com/exchange/originaldisplayto

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

© 2000-2001 Microsoft Corporation. All rights reserved.


originalsendername Field

Used in reports for in Outlook Web Access, Shows the original name of the sender of a report.

Full Name

http://schemas.microsoft.com/exchange/originalsendername

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

© 2000-2001 Microsoft Corporation. All rights reserved.


originalsubject Field

Used for reports in Outlook Web Access; shows the original subject of a report.

Full Name

http://schemas.microsoft.com/exchange/originalsubject

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

© 2000-2001 Microsoft Corporation. All rights reserved.


outlookfolderclass Field

Provides access to the MAPI PR_CONTAINER_CLASS.

Full Name

http://schemas.microsoft.com/exchange/outlookfolderclass

Content Class

urn:content-classes:folder

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Example

IPF.Note

IPF.Appointment

© 2000-2001 Microsoft Corporation. All rights reserved.


outlookmessageclass Field

Provides access to the MAPI PR_MESSAGE_CLASS.

Full Name

http://schemas.microsoft.com/exchange/outlookmessageclass

Content Class

urn:content:classes:item

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Example

IPM.Note

IPM.Note.Foo

IPM.Post.Foo.Bar

© 2000-2001 Microsoft Corporation. All rights reserved.


patternend Field

Read-only. The absolute maximum time when an instance of a recurring appointment ends. If there are no exceptions, this is the end time of the last instance.

Full Name

http://schemas.microsoft.com/exchange/patternend

Content Class

urn:content-classes:appointment

OLE DB Type

DBTYPE_FILETIME

Variant Subtype

[Visual Basic] DATE

[C++] VT_DATE

Example

"12/1/1999 12:12:00 AM"

© 2000-2001 Microsoft Corporation. All rights reserved.


patternstart Field

Read-only. The absolute minimum time when an instance of a recurring appointment starts. If there are no exceptions, this is the start time of the first instance.

Full Name

http://schemas.microsoft.com/exchange/patternstart

Content Class

urn:content-classes:appointment

OLE DB Type

DBTYPE_FILETIME

Variant Subtype

[Visual Basic] DateTime

[C++] VT_DATETIME

Example

"12/1/1999 12:12:00 AM"

© 2000-2001 Microsoft Corporation. All rights reserved.


permanenturl Field

This is the field for a permanent URL that can always be used to access an item, even if the URL to the item is changed by renaming or moving it.

Full Name

http://schemas.microsoft.com/exchange/permanenturl

Content Class

urn:content:classes:item

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

© 2000-2001 Microsoft Corporation. All rights reserved.


publicdelegates Field

This property specifies the list of URLs of all users that have access to the mailbox.

Full Name

http://schemas.microsoft.com/exchange/publicdelegates

OLE DB Type

VECTOR WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

© 2000-2001 Microsoft Corporation. All rights reserved.


publicfolderemailaddress Field

E-mail address of a public folder.

Full Name

http://schemas.microsoft.com/exchange/publicfolderemailaddress

Content Class

urn:content-classes:folder

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

© 2000-2001 Microsoft Corporation. All rights reserved.


publishinaddressbook Field

Controls whether or not an address book should display in a mail-enabled public folder.

Full Name

http://schemas.microsoft.com/exchange/publishinaddressbook

OLE DB Type

DBTYPE_BOOL

Variant Subtype

[Visual Basic] Boolean

[C++] VARIANT_BOOL

© 2000-2001 Microsoft Corporation. All rights reserved.


receipttime Field

Used by Microsoft Outlook Web Access to show received time for a message as reported in a delivery report.

Full Name

http://schemas.microsoft.com/exchange/receipttime

OLE DB Type

DBTYPE_DBTIMESTAMP

Variant Subtype

[Visual Basic] DateTime

[C++] VT_DATE

© 2000-2001 Microsoft Corporation. All rights reserved.


recipientlimit Field

The maximum number of people to whom the recipient can send e-mail.

Full Name

http://schemas.microsoft.com/exchange/recipientlimit

OLE DB Type

DBTYPE_I4

Variant Subtype

[Visual Basic] Long

[C++] long

© 2000-2001 Microsoft Corporation. All rights reserved.


replicationmessagepriority Field

Replication message priorities is configured in the Exchange System Manager. Replication message priorities maps to Normal, Not Urgent, and on a per folder basis.

Full Name

http://schemas.microsoft.com/exchange/replicationmessagepriority

Content Class

urn:content-classes:folder

OLE DB Type

DBTYPE_I4

Variant Subtype

[Visual Basic] Long

[C++] long

© 2000-2001 Microsoft Corporation. All rights reserved.


replicationschedule Field

Binary property representing the replication schedule on a per-folder basis.

Full Name

http://schemas.microsoft.com/exchange/replicationschedule

Content Class

urn:content-classes:folder

OLE DB Type

DBTYPE_BYTES

Variant Subtype

[Visual Basic] Bytes

[C++] BYTE [length]


replicationstyle Field

One of the replication styles available for public folders in a per folder basis.

Full Name

http://schemas.microsoft.com/exchange/replicationstyle

Content Class

urn:content-classes:folder

OLE DB Type

DBTYPE_UI4

Variant Subtype

[Visual Basic] Integer

[C++] unsigned int

© 2000-2001 Microsoft Corporation. All rights reserved.


sensitivity Field

Message and appointment sensitivity: None – 0; Personal – 1; Private – 2; Company Confidential – 3.

Full Name

http://schemas.microsoft.com/exchange/sensitivity

Content Class

urn:content-classes:appointment

urn-content-classes:message

OLE DB Type

DBTYPE_I4

Variant Subtype

[Visual Basic] Long

[C++] long

© 2000-2001 Microsoft Corporation. All rights reserved.


shortdateformat Field

Used by the Microsoft® Outlook Web Access to indicate the short date format to use for a user.

Full Name

http://schemas.microsoft.com/exchange/shortdateformat

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

© 2000-2001 Microsoft Corporation. All rights reserved.


storagequotaissuewarninglimit Field

The storage size in kilobytes (KB) of a public folder after a storage quota warning is issued for the folder.

Full Name

http://schemas.microsoft.com/exchange/storagequotaissuewarninglimit

OLE DB Type

DBTYPE_UI4

Variant Subtype

[Visual Basic] Ingeger

[C++] unsigned int

© 2000-2001 Microsoft Corporation. All rights reserved.


targetaddress Field

The address where e-mail is redirected when the intended recipient is unavailable.

Full Name

http://schemas.microsoft.com/exchange/targetaddress

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

© 2000-2001 Microsoft Corporation. All rights reserved.


textencodedoraddress Field

This property specifies the primary X.400 address used for the recipient.

Full Name

http://schemas.microsoft.com/exchange/textencodedoraddress

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

© 2000-2001 Microsoft Corporation. All rights reserved.


timeformat Field

Used by Microsoft® Outlook Web Access to indicate the time format of the user.

Full Name

http://schemas.microsoft.com/exchange/timeformat

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

© 2000-2001 Microsoft Corporation. All rights reserved.


timezone Field

Used by Microsoft® Outlook Web Access to indicate the timezone used for calendaring.

Full Name

http://schemas.microsoft.com/exchange/timezone

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

© 2000-2001 Microsoft Corporation. All rights reserved.


weekstartday Field

Used by Microsoft® Outlook® Web Access to indicate a user’s preference that indicates the first day of the week.

Full Name

http://schemas.microsoft.com/exchange/weekstartday

OLE DB Type

DBTYPE_I4

Variant Subtype

[Visual Basic] Long

[C++] long

© 2000-2001 Microsoft Corporation. All rights reserved.


workdayendtime Field

End of the work day.

Full Name

http://schemas.microsoft.com/exchange/workdayendtime

OLE DB Type

DBTYPE_I4

Variant Subtype

[Visual Basic] Long

[C++] long

Example

17


workdays Field

Used by Microsoft® Outlook Web Access to indicate the work days for a user.

Full Name

http://schemas.microsoft.com/exchange/workdays

OLE DB Type

DBTYPE_I4

Variant Subtype

[Visual Basic] Long

[C++] long

© 2000-2001 Microsoft Corporation. All rights reserved.


workdaystarttime Field

Used by a Web client to indicate the time of day that work starts for a user.

Full Name

http://schemas.microsoft.com/exchange/workdaystarttime

OLE DB Type

DBTYPE_I4

Variant Subtype

[Visual Basic] Long

[C++] long

© 2000-2001 Microsoft Corporation. All rights reserved.


yomifirstname Field

Used in Japan for the searchable or phonetic spelling for a Japanese firstname.

Full Name

http://schemas.microsoft.com/exchange/yomifirstname

Content Class

urn:content-classes:person

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

© 2000-2001 Microsoft Corporation. All rights reserved.


yomilastname Field

Used in Japan for the searchable or phonetic spelling for a Japanese lastname.

Full Name

http://schemas.microsoft.com/exchange/yomilastname

Content Class

urn:content-classes:person

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

© 2000-2001 Microsoft Corporation. All rights reserved.


yomiorganization Field

Used in a Japanese organization

Full Name

http://schemas.microsoft.com/exchange/yomiorganization

Content Class

urn:content-classes:person

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

© 2000-2001 Microsoft Corporation. All rights reserved.


http://schemas.microsoft.com/exchange/events/ Namespace

The http://schemas.microsoft.com/exchange/events/ namespace defines fields used when creating event registration items in the Microsoft® Web Storage System.


Criteria Field

A SQL WHERE condition that restricts the criteria for when an event fires.

Full Name

http://schemas.microsoft.com/exchange/events/Criteria

Variant Subtype

[Visual Basic] String

[C++] VT_BSTR

OLE DB Type

DBTYPE_WSTR

Remarks

The Criteria field applies to the OnSave, OnSyncSave, and OnSyncDelete events.

The Criteria field is optional. If the Criteria field is set, then the event sink will be notified if the criteria's SQL WHERE conditions are satisfied. The following conditions are supported:

AND, OR, NOT, EXISTS

Use of the CONTAINS condition in this binding property is not supported.

Use double quotes for property names and single quotes for strings to be evaluated. Custom properties must be explicitly cast to the proper type. For example:

"WHERE cast($"MyNumber"$ as 'i4')<>15"

The WHERE clause Criteria is limited to information in the item. It is not possible to specify conditions on data outside of this item. (The "$" character escapes the double quotes.)

Example

WHERE DAV:ishidden = FALSE and DAV:contentclass = "urn:content-classes:item"

WHERE status=’active’ AND DAV:displayname = ’mjp.eml'”

WHERE status= ’active’ AND DAV:displayname=’mjp.eml’ AND urn:schemas:mailheader:subject = 'Expense Report' AND (DAV:ishidden = ‘FALSE’ ) AND urn:schemas:httpmail:has attachment = TRUE


Enabled Field

A Boolean value that indicates if an event registration is enabled.

Full Name

http://schemas.microsoft.com/exchange/events/Enabled

Variant Subtype

[Visual Basic] Boolean

[C++] VT_BOOL

OLE DB Type

DBTYPE_BOOL

Default

True (VARIANT_TRUE)

Remarks

Exchange does not provide event notifications for the registration item if this property is set to False (VARIANT_FALSE).


EventMethod Field

A list of events to receive event notification.

Full Name

http://schemas.microsoft.com/exchange/events/EventMethod

Variant Subtype

[Visual Basic] Variant() of Strings

[C++] VT_ARRAY | VT_VARIANT

OLE DB Type

DBTYPE_ARRAY | DBTYPE_VARIANT

Remarks

This property can only contain event names from the same category. Each row in the following table lists these event categories:

Event Category | Event Names
Store events | OnSave, OnDelete, OnSyncSave, OnSyncDelete
System events | OnMDBStartup, OnMDBShutdown
System events (OnTimer) | OnTimer


MatchScope Field

Defines where the event will fire relative to where it is saved. Also defines if the event is for items, folders, or both.

Full Name

http://schemas.microsoft.com/exchange/events/MatchScope

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] VT_BSTR

Default

Default is "EXACT".

Remarks

For synchronous events this value can be:

"ANY"

"DEEP"

"SHALLOW"

For asynchronous events this value can be:

"DEEP"

"EXACT"

The following table defines the scope values:

Scope Value | Definition
"ANY" | Within the scope of the MDB.
"DEEP" | Standard deep traversal.
"EXACT" | The folder only.
"SHALLOW" | The folder only.

"DEEP" can only be registered at the top-level folder.

This property is not valid for system events.

Example

"DEEP"

© 2000-2001 Microsoft Corporation. All rights reserved.


Priority Field

The priority of the event registration with respect to other event registrations for the same events.

Full Name

http://schemas.microsoft.com/exchange/events/Priority

Variant Subtype

[Visual Basic] Long

[C++] VT_UI4

OLE DB Type

DBTYPE_UI4

Default

0x0000FFFF (65,535)

Remarks

Event sinks are notified in priority order, with 0 being the highest priority. Event registrations with the same priority are notified in an indeterminate order.

This property is only valid for synchronous event sink bindings. No order is implied for notifications of asynchronous events or system events.

See Also

Event Notification Priority

© 2000-2001 Microsoft Corporation. All rights reserved.


ScriptUrl Field

When using the scripting host, this property specifies the path (URL) to the file containing the script code to execute.

Full Name

http://schemas.microsoft.com/exchange/events/ScriptUrl

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] VT_BSTR

Remarks

The URL can be to a script file located in the Web Storage System or on a file system. Both the OLE DB http: and file: URI schemes are supported. However, the local Web Storage System OLE DB provider is always used if the URL is expressed using the file: or http: schemes. You cannot store the script file on a remote machine, and the script must be accessible by the process under which the Web Storage System process is executing.

Example

"d:\onsavescript.vbs"

"file://./backofficestorage/domain.microsoft.com/public folders/common/scripts/myonsavescript1.vbs"

See Also

Script Host Sink

© 2000-2001 Microsoft Corporation. All rights reserved.


SinkClass Field

The COM class identifier (CLSID) in registry format, or the programmatic identifier (ProgID), of the event sink COM class.

Full Name

http://schemas.microsoft.com/exchange/events/SinkClass

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] VT_BSTR

Remarks

When using a CLSID, the format should be as follows:

{0cfb5d5c-fafe-11d3-9ad3-00bf4d9137b7f}

The enclosing brackets are required.

To use the Script Host Sink, specify the programmatic identifier Exoledb.ScriptEventSink.1.


TimerExpiryTime Field

The absolute time at which Exchange no longer notifies event sinks of the OnTimer event.

Full Name

http://schemas.microsoft.com/exchange/events/TimerExpiryTime

OLE DB Type

DBTYPE_DATE or DBTYPE_FILETIME

Variant Subtype

[Visual Basic] Date

[C++] VT_DATE

Default

No Default. It is an optional field.

Remarks

The expiration time is an absolute time specifying when this event timer ends.

If this property is not set, the binding does not expire.

This property is only valid for OnTimer events.

See Also

TimerStartTime

© 2000-2001 Microsoft Corporation. All rights reserved.


TimerInterval Field

The period (time interval) in minutes between OnTimer event notifications.

Full Name

http://schemas.microsoft.com/exchange/events/TimerInterval

OLE DB Type

DBTYPE_I2

Variant Subtype

[Visual Basic] Integer

[C++] VT_I2

Default

1440

Remarks

If this property is not set, then Exchange notifies the event sink only once. This single notification occurs TimerInterval minutes after the event registration's TimerStartTime property.

This property is only valid for OnTimer event registrations.

See Also

TimerStartTime

© 2000-2001 Microsoft Corporation. All rights reserved.


TimerStartTime Field

The absolute time at which Exchange begins notifying event sinks of the OnTimer event.

Full Name

http://schemas.microsoft.com/exchange/events/TimerStartTime

OLE DB Type

DBTYPE_DATE or DBTYPE_FILETIME

Variant Subtype

[Visual Basic] Date

[C++] VT_DATE

Remarks

The absolute time that the OnTimer event begins firing.

If this property is not set, Exchange will begin notifying the event sink immediately after the event registration has been created.

This property is only valid for OnTimer event registrations.

See Also

OnTimer Event

© 2000-2001 Microsoft Corporation. All rights reserved.


http://schemas.microsoft.com/exchange/security Namespace

Platform SDK: Exchange 2000 Server

http://schemas.microsoft.com/exchange/security/ Namespace

The properties for the http://schemas.microsoft.com/exchange/security/ namespace contain XML strings that describe Microsoft® Windows® 2000 security descriptors and security identifiers (SIDs). The Web Storage System parses the XML and renders it into binary values for Windows 2000 security, and also extracts binary information into XML for property inquiries. XML is only used for the transfer format, not for persistence.

The following table lists the properties in this namespace according to whether they are security descriptors or role SIDs. A role SID differs from a Windows 2000 SID because role SID is exclusively a Microsoft Exchange 2000 security feature. Each role SID property contains a list of SIDs that ACEs (access-control entries) in a discretionary access-control list (DACL) can use to determine whether to grant or deny access to a Microsoft Web Storage System folder, item, or property.

The Web Storage System uses SIDs to calculate Web Storage System mailing and document management properties, as well as to implement security roles. A role property in this namespace contains a list of SIDs.

Descriptor Properties | Role SID Properties
admindescriptor descriptor | creator lastmodifier originalauthor originalsender originalsentrepresenting originator readreceiptfrom receivedby receivedrepresenting reportdestination reportfrom sender sentrepresenting


admindescriptor

This property is the XML representation of the security descriptor for a Web Storage System folder or collection. An admin security descriptor identifies the object's owner and primary group. It can also contain a DACL that controls access to the object, and a system access-control list (SACL) that controls the logging of attempts to access the object.

Full Name

http://schemas.microsoft.com/exchange/security/admindescriptor

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Remarks

You must have the proper access rights (READ_CONTROL, WRITE_DAC, or WRITE_OWNER) to update the respective parts of the item's descriptor.

Updating an Item’s Security Descriptor

© 2000-2001 Microsoft Corporation. All rights reserved.


creator

This property is the XML representation of a security identifier of the creator of the Web Storage System item.

Full Name

http://schemas.microsoft.com/exchange/security/creator

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

© 2000-2001 Microsoft Corporation. All rights reserved.


descriptor

This property is the XML representation of the security descriptor for a Web Storage System item. A security descriptor identifies the object's owner and primary group. It can also contain a DACL that controls access to the object, and a SACL that controls the logging of attempts to access the object.

Full Name

http://schemas.microsoft.com/exchange/security/descriptor

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Remarks

You must have the proper access rights (READ_CONTROL, WRITE_DAC, or WRITE_OWNER) to update the respective parts of the item's descriptor.

Updating an Item’s Security Descriptor

© 2000-2001 Microsoft Corporation. All rights reserved.


lastmodifier

This property is the XML representation of a security identifier of the last modifier of the Web Storage System item.

Full Name

http://schemas.microsoft.com/exchange/security/lastmodifier

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

© 2000-2001 Microsoft Corporation. All rights reserved.


originalauthor

This property is the XML representation of a security identifier of the original author of the Web Storage System item.

Full Name

http://schemas.microsoft.com/exchange/security/originalauthor

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

© 2000-2001 Microsoft Corporation. All rights reserved.


originalsender

This property is the XML representation of a security identifier of the original sender of the Web Storage System item.

Full Name

http://schemas.microsoft.com/exchange/security/originalsender

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

© 2000-2001 Microsoft Corporation. All rights reserved.


originalsentrepresenting

Reserved for future use.

Full Name

http://schemas.microsoft.com/exchange/security/originalsentrepresenting

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

© 2000-2001 Microsoft Corporation. All rights reserved.


originator

This property is the XML representation of a security identifier of the originator of the Web Storage System item.

Full Name

http://schemas.microsoft.com/exchange/security/originator

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

© 2000-2001 Microsoft Corporation. All rights reserved.


readreceiptfrom

This property is the XML representation of a security identifier of the reader of the Web Storage System item.

Full Name

http://schemas.microsoft.com/exchange/security/readreceiptfrom

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

© 2000-2001 Microsoft Corporation. All rights reserved.


receivedby

This property is the XML representation of a security identifier of the recipient of a Web Storage System item.

Full Name

http://schemas.microsoft.com/exchange/security/receivedby

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

© 2000-2001 Microsoft Corporation. All rights reserved.


receivedrepresenting

Reserved for future use.

Full Name

http://schemas.microsoft.com/exchange/security/receivedrepresenting

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

© 2000-2001 Microsoft Corporation. All rights reserved.


reportdestination

Reserved for future use.

Full Name

http://schemas.microsoft.com/exchange/security/reportdestination

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

© 2000-2001 Microsoft Corporation. All rights reserved.


reportfrom

Reserved for future use.

Full Name

http://schemas.microsoft.com/exchange/security/reportfrom

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

© 2000-2001 Microsoft Corporation. All rights reserved.


sender

This property is the XML representation of a security identifier of the sender of a Web Storage System item.

Full Name

http://schemas.microsoft.com/exchange/security/sender

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

© 2000-2001 Microsoft Corporation. All rights reserved.


sentrepresenting

Reserved for future use.

Full Name

http://schemas.microsoft.com/exchange/security/sentrepresenting

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

© 2000-2001 Microsoft Corporation. All rights reserved.


http://schemas.microsoft.com/mapi/ Namespace

The http://schemas.microsoft.com/mapi/ namespace is used to directly access Messaging Application Program Interface (MAPI) properties in the Exchange store. The namespace consists of three sub namespaces: proptag, id, and string. The following table shows these subnamespaces and their descriptions.

Sub Namespace | Description
proptag | This namespace is used to access MAPI properties in the Exchange store. You can access these properties through an OLE DB provider or through WebDAV by appending the hexadecimal property tag value to the namespace prefix: http://schemas.microsoft.com/mapi/proptag/value The hexadecimal value should follow the character "x" in the name. For example, the PR_SUBJECT MAPI property can be accessed using the name http://schemas.microsoft.com/mapi/proptag/x0037001E. The full property tag value must be used.
id | This namespace is used to access id-named MAPI properties in the Exchange store. You can access these properties through an OLE DB provider or through WebDAV by appending the namespace GUID in string format for the property set followed by the hexadecimal identifier for the property: http://schemas.microsoft.com/mapi/id/{propset GUID}/value For example, http://schemas.microsoft.com/mapi/id/{3f0a69e0-7f56-11d2-b536-00aa00bbb6e6}/xfeedface
string | This namespace is used to access string-named MAPI properties in the Exchange store. You can access these properties through an OLE DB provider or through WebDAV by appending the namespace GUID in string format for the property set followed by the name (string) of the property: http://schemas.microsoft.com/mapi/string/{propset GUID}/name For example, http://schemas.microsoft.com/mapi/string/{3f0a69e0-7f56-11d2-b536-00aa00bbb6e6}/myproperty

[Visual Basic]
Dim Rec as New ADODB.Record
Dim Flds as ADODB.Fields

' assume we have the URL to an item in
' a public folder. Assume further that string-named
' properties exist for it and are set using some MAPI form
' The namespace for the property set will be
' {3f0a69e0-7f56-11d2-b536-00aa00bbb6e6}
' and the properties are called
' prop1,prop2, and prop3. Each property is a string

Dim strProp1 as String
Dim strProp2 as String
Dim strProp3 as String

Rec.Open "http://server/public/public folders/somefolder/item3.eml", , adModeReadWrite

Set Flds = Rec.Fields

strProp1 = Flds("http://schemas.microsoft.com/mapi/id/{3f0a69e0-7f56-11d2-b536-00aa00bbb6e6}/prop1").Value

strProp2 = Flds("http://schemas.microsoft.com/mapi/id/{3f0a69e0-7f56-11d2-b536-00aa00bbb6e6}/prop2").Value

strProp3 = Flds("http://schemas.microsoft.com/mapi/id/{3f0a69e0-7f56-11d2-b536-00aa00bbb6e6}/prop3").Value
[VBScript]
Dim Rec
Dim Flds

Set Rec = CreateObject("ADODB.Record")

' assume we have the URL to an item in
' a public folder. Assume further that string-named
' properties exist for it and are set using some MAPI form
' The namespace for the property set will be
' {3f0a69e0-7f56-11d2-b536-00aa00bbb6e6}
' and the properties are called
' prop1,prop2, and prop3. Each property is a string

Dim strProp1
Dim strProp2
Dim strProp3

Rec.Open "http://server/public/public folders/somefolder/item3.eml", , adModeReadWrite

Set Flds = Rec.Fields

strProp1 = Flds("http://schemas.microsoft.com/mapi/id/{3f0a69e0-7f56-11d2-b536-00aa00bbb6e6}/prop1").Value

strProp2 = Flds("http://schemas.microsoft.com/mapi/id/{3f0a69e0-7f56-11d2-b536-00aa00bbb6e6}/prop2").Value

strProp3 = Flds("http://schemas.microsoft.com/mapi/id/{3f0a69e0-7f56-11d2-b536-00aa00bbb6e6}/prop3").Value


urn:schemas:calendar: Namespace

The urn:schemas:calendar: namespace contains fields used with Appointment, CalendarMessage, CalendarPart, Configuration, Exception, and RecurrencePattern objects.


alldayevent Field

This field specifies whether an appointment is for an entire day. Setting this field does not affect the start time or end time of an appointment or meeting.

This field is also exposed as the AllDayEvent property of the IAppointment interface.

Full Name

urn:schemas:calendar:alldayevent

Content Class

urn:content-classes:appointment

Named Constant

CdoCalendar.cdoAllDayEvent

Variant Subtype

[Visual Basic] Boolean

[C++] VARIANT_BOOL

OLE DB Type

DBTYPE_BOOL

Example

FALSE

© 2000-2001 Microsoft Corporation. All rights reserved.


attendeerole Field

Specifies the role of an attendee for an appointment: chair, required, optional, or not attending but copied for reference.

Use values from the CdoAttendeeRoleValues enumeration.

Full Name

urn:schemas:calendar:attendeerole

Named Constant

CdoCalendar.cdoAttendeeRole

Variant Subtype

[Visual Basic] Long

[C++] long

OLE DB Type

DBTYPE_I4

Example

cdoRequiredParticipant


attendeestatus Field

Specifies the status of an attendee for an appointment: accepted, declined, tentative, or has not responded.

Use values from the CdoAttendeeStatusValues enumeration.

Full Name

urn:schemas:calendar:attendeestatus

Named Constant

CdoCalendar.cdoAttendeeStatus

Variant Subtype

[Visual Basic] Long

[C++] long

OLE DB Type

DBTYPE_I4

Example

cdoAccepted


busystatus Field

This field is also exposed as the BusyStatus property of the IAppointment interface.

Full Name

urn:schemas:calendar:busystatus

Content Class

urn:content-classes:appointment

Named Constant

CdoCalendar.cdoBusyStatus

Variant Subtype

[Visual Basic] String

[C++] BSTR

OLE DB Type

DBTYPE_WSTR

Remarks

Use the constant values in CdoBusyStatusValues:

Constant | Value
cdoBusy | Busy
cdoFree | Free
cdoTentative | Tentative
cdoOOF | OOF

Example

cdoBusyStatusFree


contact Field

Contains a person's name as a contact for an appointment.

This field is also exposed as the Contact property of the IAppointment interface.

Full Name

urn:schemas:calendar:contact

Content Class

urn:content-classes:appointment

Named Constant

CdoCalendar.cdoContact

Variant Subtype

[Visual Basic] String

[C++] BSTR

OLE DB Type

DBTYPE_WSTR

Example

"Pat Smith"

© 2000-2001 Microsoft Corporation. All rights reserved.


contacturl Field

Contains a URL for accessing contact information in HTML format.

This field is also exposed as the ContactURL property of the IAppointment interface.

Full Name

urn:schemas:calendar:contacturl

Content Class

urn:content-classes:appointment

Named Constant

CdoCalendar.cdoContactURL

OLE DB Type

DBTYPE_WSTR

Example

"http://www.microsoft.com/patsmith"

© 2000-2001 Microsoft Corporation. All rights reserved.


created Field

The date and time an appointment was created in the originator's calendar. This value is the same in the organizer's copy of the appointment and in each attendee's copy.

Full Name

urn:schemas:calendar:created

Content Class

urn:content-classes:appointment

Named Constant

CdoCalendar.cdoCreated

Variant Subtype

[Visual Basic] Date

[C++] DATE

OLE DB Type

DBTYPE_DBTIMESTAMP

Example

"09/20/99 1:20PM"

© 2000-2001 Microsoft Corporation. All rights reserved.


descriptionurl Field

A URL to a resource containing a description of the appointment or meeting. This property corresponds to the iCalendar, RFC 2445, ALTREP DESCRIPTION field.

Full Name

urn:schemas:calendar:descriptionurl

Content Class

urn:content-classes:appointment

Named Constant

CdoCalendar.cdoDescriptionURL

OLE DB Type

DBTYPE_WSTR

Variant Sub-Type

[Visual Basic] String

[C++] BSTR

Remarks

The iCAL (RFC 2445) ALTREP DESCRIPTION field is defined as a Uniform Resource Identifier (URI), and URIs can only be made up of US-ASCII characters. However, CDO will not generate an error if you use a URL that does contain non US-ASCII characters. CDO always assumes that US-ASCII characters are always used in URIs contained by this property and therefore does not perform character-encoding conversions.

Example

"http://www.myfiles.com/info.htm"

© 2000-2001 Microsoft Corporation. All rights reserved.


dtend Field

Appointment ending date and time.

This field is also exposed as the EndTime property of the IAppointment interface.

Full Name

urn:schemas:calendar:dtend

Content Class

urn:content-classes:appointment

Named Constant

CdoCalendar.cdoDTEnd

Variant Subtype

[Visual Basic] Date

[C++] DATE

OLE DB Type

DBTYPE_DBTIMESTAMP

Example

"10/3/99 1:30PM"

© 2000-2001 Microsoft Corporation. All rights reserved.


dtstamp Field

The date and time the iCalendar object is created. This value is updated by CDO when the IAppointment.CreateRequest or IAppointment.Invite method is called.

Full Name

urn:schemas:calendar:dtstamp

Content Class

urn:content-classes:appointment

Named Constant

CdoCalendar.cdoDTStamp

Variant Subtype

[Visual Basic] Date

[C++] DATE

OLE DB Type

DBTYPE_DBTIMESTAMP

Example

"10/3/99 1:30PM"

© 2000-2001 Microsoft Corporation. All rights reserved.


dtstart Field

The starting date and time of an appointment.

This field is also exposed as the StartTime property of the IAppointment interface.

Full Name

urn:schemas:calendar:dtstart

Content Class

urn:content-classes:appointment

Named Constant

CdoCalendar.cdoDTStart

Variant Subtype

[Visual Basic] Date

[C++] DATE

OLE DB Type

DBTYPE_DBTIMESTAMP

Example

"10/3/99 1:30PM"

© 2000-2001 Microsoft Corporation. All rights reserved.


duration Field

The duration of the appointment in seconds.

This field is also exposed as the Duration property of the IAppointment interface.

Full Name

urn:schemas:calendar:duration

Content Class

urn:content-classes:appointment

Named Constant

CdoCalendar.cdoDuration

Variant Subtype

[Visual Basic] Long

[C++] long

OLE DB Type

DBTYPE_I4

Example

3600


exdate Field

The list of recurring appointment instances that are deleted.

Full Name

urn:schemas:calendar:exdate

Content Class

urn:content-classes:appointment

Named Constant

CdoCalendar.cdoExDate

Variant Subtype

[Visual Basic] Variants() (String)

[C++] VT_ARRAY | VT_VARIANT (VT_BSTR)

OLE DB Type

DBTYPE_VECTOR | DBTYPE_VARIANT

Example

"19990402T010000Z"
"19990403T010000Z"
"19990404T010000Z"

© 2000-2001 Microsoft Corporation. All rights reserved.


exrule Field

This is the complete recurrence/exception rule string as defined in the iCalendar standard.

Full Name

urn:schemas:calendar:exrule

Content Class

urn:content-classes:appointment

Named Constant

CdoCalendar.cdoExRule

Variant Subtype

[Visual Basic] String

[C++] BSTR

OLE DB Type

DBTYPE_WSTR

Example

"EXRULE:FREQ=WEEKLY;COUNT=4;INTERVAL=2;BYDAY=TU,TH"


fburl Field

The URL of the free/busy public folder.

Full Name

urn:schemas:calendar:fburl

Content Class

urn:content-classes:person

Named Constant

CdoCalendar.cdoFburl

Variant Subtype

[Visual Basic] String

[C++] BSTR

OLE DB Type

DBTYPE_WSTR

Example

"file://myserver/?"

© 2000-2001 Microsoft Corporation. All rights reserved.


geolatitude Field

Contains the geographical latitude of an appointment's location. Positive values from 0 to 90 are degrees north latitude. Negative values from 0 to -90 are degrees south latitude.

This field is also exposed as the GEOLatitude property of the IAppointment interface.

Full Name

urn:schemas:calendar:geolatitude

Content Class

urn:content-classes:person

urn:content-classes:appointment

Named Constant

CdoCalendar.cdoGEOLatitude

Variant Subtype

[Visual Basic] Double

[C++] double

OLE DB Type

DBTYPE_R8

Remarks

You must set both geolatitude and geolongitude for this field to be saved. If you only set one of these two fields, the value is not saved.

Example

47.63880


geolongitude Field

Contains the geographical longitude of an appointment's location. Positive values from 0 to 180 are degrees east longitude. Negative values from 0 to -180 are degrees west longitude.

This field is also exposed as the GEOLongitude property of the IAppointment interface.

Full Name

urn:schemas:calendar:geolongitude

Content Class

urn:content-classes:person

urn:content-classes:appointment

Named Constant

CdoCalendar.cdoGEOLongitude

Variant Subtype

[Visual Basic] Double

[C++] double

OLE DB Type

DBTYPE_R8

Remarks

You must set both geolatitude and geolongitude for this field to be saved. If you only set one of these two fields, the value is not saved.

Example

-122.13360


instancetype Field

Indicates the type of appointment: single appointment, master recurring appointment, instance of a recurring appointment, or exception to a recurring appointment. These values are described by the CdoInstanceType enumeration.

Do not change this value.

Note The value of the instancetype field is not always correct. If instancetype is cdoMaster, but there are no items with Type=ADD in either the Recurrence Patterns or Exceptions collections, then the correct value is cdoSingle. When the appointment is saved, instancetype is set to cdoSingle.

If the instancetype is cdoSingle, but there is at least one item with Type=ADD in either the Recurrence Patterns or Exceptions collections, then the correct value is cdoMaster. When the appointment is saved, instancetype is set to cdoMaster.

If the instancetype is cdoInstance or cdoException, the instancetype value is always correct.

Full Name

urn:schemas:calendar:instancetype

Content Class

urn:content-classes:appointment

Named Constant

CdoCalendar.cdoInstanceType

Variant Subtype

[Visual Basic] Long

[C++] long

OLE DB Type

DBTYPE_I4

Example

cdoMaster


isorganizer Field

Specifies if an attendee is the organizer of an appointment.

Full Name

urn:schemas:calendar:isorganizer

Named Constant

CdoCalendar.cdoIsOrganizer

Variant Subtype

[Visual Basic] Boolean

[C++] VARIANT_BOOL

OLE DB Type

DBTYPE_BOOL

Example

TRUE

© 2000-2001 Microsoft Corporation. All rights reserved.


lastmodified Field

This property is the value stored in the appointment stream and is separate from the DAV:getlastmodified. This is not mapped to the MAPI PR_LAST_MODIFICATION_TIME.

Full Name

urn:schemas:calendar:lastmodified

Content Class

urn:content-classes:appointment

Named Constant

CdoCalendar.cdoLastModified

OLE DB Type

DBTIMESTAMP

Variant Subtype

[Visual Basic] String

[C++] BSTR

Example

"12/1/98 2:30PM"

© 2000-2001 Microsoft Corporation. All rights reserved.


lastmodifiedtime Field

The last time an appointment was saved. This field is stored in the organizer's copy and in each attendee's copy of the appointment. The value can be different in each copy. This value is updated when any method saves an appointment.

Full Name

urn:schemas:calendar:lastmodifiedtime

Named Constant

CdoCalendar.cdoCalendarLastModifiedTime

Variant Subtype

[Visual Basic] Date

[C++] DATE

OLE DB Type

DBTYPE_DBTIMESTAMP

Example

"12/1/98 2:30PM"

© 2000-2001 Microsoft Corporation. All rights reserved.


location Field

Contains an appointment's meeting location.

Full Name

urn:schemas:calendar:location

Content Class

urn:content-classes:appointment

Named Constant

CdoCalendar.cdoLocation

Variant Subtype

[Visual Basic] String

[C++] BSTR

OLE DB Type

DBTYPE_WSTR

Remarks

This field is also exposed as the Location property of the IAppointment interface.

Example

"Building B, Room 12"

© 2000-2001 Microsoft Corporation. All rights reserved.


locationurl Field

Contains a URL for accessing location information in HTML format.

Full Name

urn:schemas:calendar:locationurl

Content Class

urn:content-classes:appointment

Named Constant

CdoCalendar.cdoLocationURL

Variant Subtype

[Visual Basic] String

[C++] BSTR

OLE DB Type

DBTYPE_WSTR

Remarks

This field is also exposed as the LocationURL property of the IAppointment interface.

Example

"http://www.microsoft.com/maps/building_b.htm"


meetingstatus Field

The status of an appointment: Tentative, Confirmed, or Cancelled.

Full Name

urn:schemas:calendar:meetingstatus

Content Class

urn:content-classes:appointment

Named Constant

CdoCalendar.cdoMeetingStatus

Variant Subtype

[Visual Basic] String

[C++] BSTR

OLE DB Type

DBTYPE_WSTR

Remarks

Use the constant values in CdoMeetingStatusValues:

Constant | Value
cdoMeetingStatusCancelled | Cancelled
cdoMeetingStatusConfirmed | Confirmed
cdoMeetingStatusTentative | Tentative

This field is also exposed as the MeetingStatus property of the IAppointment interface.

Example

cdoMeetingStatusConfirmed


method Field

Specifies the iCalendar object method associated with an appointment object.

Full Name

urn:schemas:calendar:method

Content Class

urn:content-classes:appointment

un:content-classes:calendarmessage

Named Constant

CdoCalendar.cdoMethod

Variant Subtype

[Visual Basic] String

[C++] BSTR

OLE DB Type

DBTYPE_WSTR

Remarks

Use the constant values in CdoMethodValues:

Constant | Value
cdoAdd | Add
cdoCancel | Cancel
cdoCounter | Counter
cdoDeclineCounter | DeclineCounter
cdoPublish | Publish
cdoRefresh | Refresh
cdoReply | Reply
cdoRequest | Request

Example

cdoReply


organizer Field

The SMTP e-mail name of the organizer of a meeting. This value corresponds to the meeting attendee with the isorganizer field set to TRUE.

Full Name

urn:schemas:calendar:organizer

Named Constant

None

Variant Subtype

[Visual Basic] String

[C++] BSTR

OLE DB Type

DBTYPE_WSTR

Example

"someone@microsoft.com"

© 2000-2001 Microsoft Corporation. All rights reserved.


prodid Field

An identifier of the product that created the iCalendar-formatted stream.

Full Name

urn:schemas:calendar:prodid

Named Constant

CdoCalendar.cdoProdId

Variant Subtype

[Visual Basic] String

[C++] BSTR

OLE DB Type

DBTYPE_WSTR

Example

"PRODID:-//Microsoft Corporation//NONSGML NewProduct//EN"


rdate Field

Contains an array of appointment instances that are additions to a recurring appointment. The instances are stored as the dates and times of the appointment.

Full Name

urn:schemas:calendar:rdate

Content Class

urn:content-classes:appointment

Named Constant

CdoCalendar.cdoRDate

Variant Subtype

[Visual Basic] Variant() (String)

[C++] VT_ARRAY | VT_VARIANT (VT_BSTR)

OLE DB Type

DBTYPE_VECTOR | DBTYPE_VARIANT (DBTYPE_WSTR)

Example

"19990304T123000Z"
"19990504T123000Z"
"19990704T123000Z"
"19990904T123000Z"

© 2000-2001 Microsoft Corporation. All rights reserved.


recurrenceid Field

A recurrence identifier that identifies a specific instance of a recurring appointment. It is used with the sequence field to uniquely identify the instance. The value of the recurrence identifier is the starting date and time of the specific instance.

The recurrenceidrange field can modify the meaning of the recurrenceid field to refer to multiple instances of a recurring appointment.

Full Name

urn:schemas:calendar:recurrenceid

Content Class

urn:content-classes:appointment

Named Constant

CdoCalendar.cdoRecurrenceId

Variant Subtype

[Visual Basic] String

[C++] BSTR

OLE DB Type

DBTYPE_WSTR

Example

"19980401T133000Z"

© 2000-2001 Microsoft Corporation. All rights reserved.


recurrenceidrange Field

Modifies the meaning of the recurrenceid field to refer to multiple instances of a recurring meeting. The value "ThisAndFuture" refers to the instance specified by the recurrenceid field, and to all later instances of the recurring appointment. The value "ThisAndPrior" refers to the instance specified by the recurrenceid field, and to all earlier instances of the recurring appointment. The default value is "None," which means the recurrenceid field refers to a single instance.

Full Name

urn:schemas:calendar:recurrenceidrange

Content Class

urn:content-classes:appointment

Named Constant

CdoCalendar.cdoRecurrenceIdRange

Variant Subtype

[Visual Basic] String

[C++] BSTR

OLE DB Type

DBTYPE_WSTR

Remarks

Use constant values from CdoRecurrenceIdRangeValues.

Constant | Value
cdoNone | None
cdoThisAndFuture | ThisAndFuture
cdoThisAndPrior | ThisAndPrior

This field is valid only for Exception objects. CDO clears the value of this field if you specify it for other objects.

Example

cdoThisAndFuture


reminderoffset Field

The number of seconds before an appointment start that a reminder is to be displayed.

For appointments that are received as iCalendar messages, this value is taken from the first VALARM calendar component of the appointment.

Full Name

urn:schemas:calendar:reminderoffset

Content Class

urn:content-classes:appointment

Named Constant

CdoCalendar.cdoReminderOffset

Variant Subtype

[Visual Basic] Long

[C++] long

OLE DB Type

DBTYPE_I4

Example

15 * 60 (15 Minutes)


replytime Field

The time a recipient replied to a meeting request. This value is updated by CDO when the IAppointment::Accept, IAppointment::AcceptTentative, or IAppointment::Decline method is called. This value can be used to determine which response is the most recent when an attendee sends more than one response to a meeting request.

This field is also exposed as the ReplyTime property of the IAppointment interface.

Full Name

urn:schemas:calendar:replytime

Content Class

urn:content-classes:appointment

Named Constant

CdoCalendar.cdoReplyTime

Variant Subtype

[Visual Basic] Date

[C++] DATE

OLE DB Type

DBTYPE_DBTIMESTAMP

Example

"2/7/99 12:12PM"

© 2000-2001 Microsoft Corporation. All rights reserved.


resources Field

A list of supportive resources for the appointment. The resources are represented as mailto URIs, and are separated by commas.

This field is also exposed as the Resources property of the IAppointment interface.

Full Name

urn:schemas:calendar:resources

Content Class

urn:content-classes:appointment

Named Constant

CdoCalendar.cdoResources

Variant Subtype

[Visual Basic] String

[C++] BSTR

OLE DB Type

DBTYPE_WSTR

Example

"conf42@microsoft.com, video1@microsoft.com"


responserequested Field

Indicates if the originator of the meeting requested a response. Returns TRUE if a response is requested.

Full Name

urn:schemas:calendar:responserequested

Content Class

urn:content-classes:appointment

Named Constant

CdoCalendar.cdoResponseRequested

Variant Subtype

[Visual Basic] Boolean

[C++] VARIANT_BOOL

OLE DB Type

DBTYPE_BOOL

Remarks

For outgoing meeting requests, if responserequested is TRUE, the iCalendar RSVP property of all attendees is set to TRUE, or if responserequested is FALSE, the RSVP property of all attendees is set to FALSE. For incoming meeting requests, if the iCalendar RSVP property of any attendee is TRUE, then responserequested is set to TRUE, or if RSVP for all attendees is FALSE, then responserequested is set to FALSE.

The responserequested field is set to FALSE if the meeting does not have an organizer. The organizer is an attendee with the IsOrganizer property set to TRUE.

This field is also exposed as the ResponseRequested property of the IAppointment interface.


rrule Field

Contains the rule for the pattern that defines a recurring appointment. The syntax is defined by the Recurrence Rule section of the iCalendar (RFC 2445) standard. The dtstart field specifies the first instance of the appointment; the rule is based on the date and time of the first instance.

Full Name

urn:schemas:calendar:rrule

Content Class

urn:content-classes:appointment

Named Constant

CdoCalendar.cdoRRule

Variant Subtype

[Visual Basic] Array of String

[C++] VT_ARRAY | VT_BSTR

OLE DB Type

DBTYPE_VECTOR | DBTYPE_WSTR

Example

"FREQ=MONTHLY"
"COUNT=10"
"BYMONTHDAY=2,15"

© 2000-2001 Microsoft Corporation. All rights reserved.


rsvp Field

Indicates if a response is expected to a meeting request. This value is synchronized to the responserequested field.

Full Name

urn:schemas:calendar:rsvp

Named Constant

CdoCalendar.cdoRSVP

Variant Subtype

[Visual Basic] Boolean

[C++] VARIANT_BOOL

OLE DB Type

DBTYPE_BOOL

Example

TRUE

© 2000-2001 Microsoft Corporation. All rights reserved.


sequence Field

The sequence number of this appointment. The sequence number is incremented by CDO when one or more of the following fields is changed: dtstart, dtend, duration, rdate, rrule, exdate, or exrule.

Do not change this value.

Full Name

urn:schemas:calendar:sequence

Content Class

urn:content-classes:appointment

Named Constant

CdoCalendar.cdoSequence

Variant Subtype

[Visual Basic] Long

[C++] long

OLE DB Type

DBTYPE_I4

Example

12


timezone Field

The time zone value of an appointment. This field enables you to define time zones that are not defined by the CdoTimeZoneId enumeration. If this field is specified, the timezoneid field is ignored.

For appointments that are received as iCalendar messages, this value is taken from the VTIMEZONE calendar component of the appointment.

Full Name

urn:schemas:calendar:timezone

Content Class

urn:content-classes:appointment

Named Constant

CdoCalendar.cdoTimeZoneURN

Variant Subtype

[Visual Basic] String

[C++] BSTR

OLE DB Type

DBTYPE_WSTR

Example

BEGIN:VTIMEZONE
TZID:Same as Pacific Time
BEGIN:STANDARD
DTSTART:16010101T020000
TZOFFSETFROM:-0700
TZOFFSETTO:-0800
RRULE:FREQ=YEARLY;WKST=MO;INTERVAL=1;BYMONTH=10;BYDAY=-1SU
END:STANDARD
BEGIN:DAYLIGHT
DTSTART:16010101T020000
TZOFFSETFROM:-0800
TZOFFSETTO:-0700
RRULE:FREQ=YEARLY;WKST=MO;INTERVAL=1;BYMONTH=4;BYDAY=1SU
END:DAYLIGHT
END:VTIMEZONE
© 2000-2001 Microsoft Corporation. All rights reserved.


timezoneid Field

The local time zone identifier.

Full Name

urn:schemas:calendar:timezoneid

Content Class

urn:content-classes:appointment

Named Constant

CdoCalendar.cdoTimeZoneIDURN

Variant Subtype

[Visual Basic] Long

[C++] long

OLE DB Type

DBTYPE_I4

Remarks

Use this value to adjust the local time with various CDO objects. The values are defined by the CdoTimeZoneID enumeration.

This field is ignored if the timezone field is specified.

Example

cdoTimeZoneIDPacific


transparent Field

Contains whether the appointment is opaque or transparent to busy time searches.

This field is also exposed as the Transparent property of the IAppointment interface.

Full Name

urn:schemas:calendar:transparent

Content Class

urn:content-classes:appointment

Named Constant

CdoCalendar.cdoTransparency

Variant Subtype

[Visual Basic] String

[C++] BSTR

OLE DB Type

DBTYPE_WSTR

Remarks

Use constant values from CdoTransparentValues.

Constant | Value
cdoOpaque | Opaque
cdoTransparent | Transparent

Example

cdoTranspOpaque


uid Field

The unique identifier for an appointment.

Full Name

urn:schemas:calendar:uid

Content Class

urn:content-classes:appointment

Named Constant

CdoCalendar.cdoCalendarUID

Variant Subtype

[Visual Basic] String

[C++] BSTR

OLE DB Type

DBTYPE_WSTR

Example

19970901T130000Z-123401@host.com

© 2000-2001 Microsoft Corporation. All rights reserved.


version Field

The identifier of the iCalendar specification version required to correctly interpret an iCalendar object.

Full Name

urn:schemas:calendar:version

Named Constant

CdoCalendar.cdoVersion

Variant Subtype

[Visual Basic] String

[C++] BSTR

OLE DB Type

DBTYPE_WSTR

Example

2.0


urn:schemas:contacts: Namespace

The urn:schemas:contacts: namespace contains a set of business and personal information management fields accessible in the Fields collection for the Person object. An example of business and personal information management fields, are childrensnames for the name of a contact's children and e-mail1 for the contact's primary e-mail address.


account Field

The account, typically the account number, for a contact.

Full Name

urn:schemas:contacts:account

Content Class

urn:content-classes:person

Named Constant

CdoContacts.cdoAccount

Variant SubType

[Visual Basic] String

[C++] BSTR

OLE DB Type

DBTYPE_WSTR

Example

"1234WA"

© 2000-2001 Microsoft Corporation. All rights reserved.


authorig Field

The identity of the person who wrote the original message or body part.

Full Name

urn:schemas:contacts:authorig

Named Constant

CdoContacts.cdoOriginalAuthor

Variant SubType

[Visual Basic] String

[C++] BSTR

OLE DB Type

DBTYPE_WSTR

Example

"Administrator"

© 2000-2001 Microsoft Corporation. All rights reserved.


bday Field

The birthday of the contact.

Full Name

urn:schemas:contacts:bday

Content Class

urn:content-classes:person

Named Constant

CdoContacts.cdoBirthday

Variant SubType

[Visual Basic] Date

[C++] DATE

OLE DB Type

DBTYPE_DBDATE

Example

"8/13"


billinginformation Field

The billing information for the contact.

Full Name

urn:schemas:contacts:billinginformation

Content Class

urn:content-classes:person

urn:content-classes:appointment

Variant SubType

[Visual Basic] String

[C++] BSTR

OLE DB Type

DBTYPE_WSTR

Example

"$100.00"


businesshomepage Field

Contains the URL to the home page of a business's Web site.

Full Name

urn:schemas:contacts:businesshomepage

Content Class

urn:content-classes:person

Variant SubType

[Visual Basic] String

[C++] BSTR

OLE DB Type

DBTYPE_WSTR

Example

"http://www.microsoft.com"

© 2000-2001 Microsoft Corporation. All rights reserved.


c Field

The work country/region code, for a contact.

Full Name

urn:schemas:contacts:c

Content Class

urn:content-classes:person

Named Constant

CdoContacts.cdoWorkCountryAbbreviation

Variant SubType

[Visual Basic] String

[C++] BSTR

Remarks

This entry is also available as the IPerson::WorkCountry property.

OLE DB Type

DBTYPE_WSTR

Example

"USA"

© 2000-2001 Microsoft Corporation. All rights reserved.


callbackphone Field

The callback telephone number, in international dialing format, of a contact.

Full Name

urn:schemas:contacts:callbackphone

Content Class

urn:content-classes:person

Named Constant

CdoContacts.cdoCallbackPhone

Variant SubType

[Visual Basic] String

[C++] BSTR

OLE DB Type

DBTYPE_WSTR

Example

"111 111 1111"


childrensnames Field

The contact’s children, with their names separated by semicolons if there are more than one entry in a field.

Full Name

urn:schemas:contacts:childrensnames

Content Class

urn:content-classes:person

Named Constant

CdoContacts.cdoChildrensNames

Variant SubType

[Visual Basic] Array of String

[C++] VT_ARRAY | VT_BSTR

OLE DB Type

DBTYPE_VECTOR | DBTYPE_WSTR

Example

"Elizabeth;Boyle"

© 2000-2001 Microsoft Corporation. All rights reserved.


cn Field

The friendly name of the contact. This field has a maximum length of 20 characters and should not be the same as a user's name in Microsoft® Exchange 2000 Server.

Full Name

urn:schemas:contacts:cn

Content Class

urn:content-classes:person

Named Constant

CdoContacts.cdoCommonName

Variant SubType

[Visual Basic] String

[C++] BSTR

OLE DB Type

DBTYPE_WSTR

Example

"Toby"

© 2000-2001 Microsoft Corporation. All rights reserved.


co Field

The work country/region for the contact.

Note If you specify a value for this field, you must also specify a value for c, the country/region abbreviation, for the object to be saved correctly to Active Directory.

Full Name

urn:schemas:contacts:co

Content Class

urn:content-classes:person

Named Constant

CdoContacts.cdoWorkCountry

Variant SubType

[Visual Basic] String

[C++] BSTR

OLE DB Type

DBTYPE_WSTR

Remarks

This entry is also available as the IPerson::WorkCountry property.

Example

"Canada"

© 2000-2001 Microsoft Corporation. All rights reserved.


computernetworkname Field

The computer network name for the contact.

Full Name

urn:schemas:contacts:computernetworkname

Content Class

urn:content-classes:person

Named Constant

CdoContacts.cdoComputerNetworkName

Variant SubType

[Visual Basic] String

[C++] BSTR

OLE DB Type

DBTYPE_WSTR

Example

"somewhere.microsoft.com"

© 2000-2001 Microsoft Corporation. All rights reserved.


customerid Field

The customer ID of the contact.

Full Name

urn:schemas:contacts:customerid

Content Class

urn:content-classes:person

Named Constant

CdoContacts.cdoCustomerId

Variant SubType

[Visual Basic] String

[C++] BSTR

OLE DB Type

DBTYPE_WSTR

Example

"1234abcd"

© 2000-2001 Microsoft Corporation. All rights reserved.


department Field

The department for the contact.

Full Name

urn:schemas:contacts:department

Content Class

urn:content-classes:person

Named Constant

CdoContacts.cdoDepartment

Variant SubType

[Visual Basic] String

[C++] BSTR

OLE DB Type

DBTYPE_WSTR

Example

"Sales"

© 2000-2001 Microsoft Corporation. All rights reserved.


dn Field

The distinguished X.500 name of the contact.

Full Name

urn:schemas:contacts:dn

Content Class

urn:content-classes:person

Named Constant

CdoContacts.cdoDistinguishedName

Variant SubType

[Visual Basic] String

[C++] BSTR

Read-only

OLE DB Type

DBTYPE_WSTR

Example

"cn=John, dc=myDomain, dc=somewhere, dc=microsoft, dc=com"


email1 Field

The primary e-mail address of the contact.

Full Name

urn:schemas:contacts:email1

Content Class

urn:content-classes:person

Named Constant

CdoContacts.cdoEmail1Address

Variant SubType

[Visual Basic] String

[C++] BSTR

OLE DB Type

DBTYPE_WSTR

Remarks

This entry is also available as the IPerson::Email property.

This field has multiple purposes:

  • As a mail attribute to hold the primary SMTP address-single valued.
  • As a multi-valued proxyAddresses attribute to hold the full list of addresses for routing, queried for Sender address. Note that each e-mail address stored in this attribute is prefixed by an address type identifier, such as SMTP or X400, followed by a colon (:). If the address type identifier is in all uppercase, that identifier is the primary address of this type, and consequently should be used as a default reply address. There can be only one primary address per address type.
  • As a single-valued textEncodedORAddress to hold the primary X.400 address.
  • As a single-valued targetAddress to hold the primary routing address for contacts, formerly CRs used for routing.

Example

"mailto:Someone@Somewhere.microsoft.com"

© 2000-2001 Microsoft Corporation. All rights reserved.


email2 Field

Secondary e-mail address of the contact.

Full Name

urn:schemas:contacts:email2

Content Class

urn:content-classes:person

Named Constant

CdoContacts.cdoEmail2Address

Variant SubType

[Visual Basic] String

[C++] BSTR

OLE DB Type

DBTYPE_WSTR

Remarks

This entry is also available as the IPerson::Email2 property.

Example

"mailto:Someone@Somewhere2.microsoft.com"


email3 Field

Tertiary e-mail address of the contact.

Full Name

urn:schemas:contacts:email3

Content Class

urn:content-classes:person

Named Constant

CdoContacts.cdoEmail3Address

Variant SubType

[Visual Basic] String

[C++] BSTR

OLE DB Type

DBTYPE_WSTR

Remarks

This entry is also available as the IPerson::Email3 property.

Example

"mailto:Someone@Somewhere3.microsoft.com"


employeenumber Field

The employee number of the contact.

Full Name

urn:schemas:contacts:employeenumber

Content Class

urn:content-classes:person

Named Constant

CdoContacts.cdoEmployeeNumber

Variant SubType

[Visual Basic] String

[C++] BSTR

OLE DB Type

DBTYPE_WSTR

Example

"217"


facsimiletelephonenumber Field

The person's work facsimile telephone number.

Full Name

urn:schemas:contacts:facsimiletelephonenumber

Content Class

urn:content-classes:person

Named Constant

CdoContacts.cdoWorkFax

Variant SubType

[Visual Basic] String

[C++] BSTR

OLE DB Type

DBTYPE_WSTR

© 2000-2001 Microsoft Corporation. All rights reserved.


fileas Field

The format of how the contact information is displayed.

Full Name

urn:schemas:contacts:fileas

Content Class

urn:content-classes:person

Named Constant

CdoContacts.cdoFileAs

Variant SubType

[Visual Basic] String

[C++] BSTR

OLE DB Type

DBTYPE_WSTR

Remarks

This entry is also available as the IPerson::FileAs property.

This entry defines how a contact is displayed. If this entry is not null, this entry contains the information that is displayed for the contact. If this entry is null, the fileasid entry defines how the contact is displayed.

Example

"Mr. Jonathan Mollerup"

© 2000-2001 Microsoft Corporation. All rights reserved.


fileasid Field

Specifies how the contact information is displayed.

Full Name

urn:schemas:contacts:fileasid

Content Class

urn:content-classes:person

Named Constant

CdoContacts.cdoFileAsId

Variant SubType

[Visual Basic] Long

[C++] Long

OLE DB Type

DBTYPE_UI4

Remarks

This entry is also available as the IPerson::FileAsMapping property.

This field identifies how the Fileas contact field is constructed from other contact fields. The values for this property are defined by the CdoFileAsMappingID enumeration.

Example

cdoFileAsMappingIDMapToLastFirst


ftpsite Field

The URL to the FTP site for the contact.

Full Name

urn:schemas:contacts:ftpsite

Content Class

urn:content-classes:person

Named Constant

CdoContacts.cdoFtpSite

Variant SubType

[Visual Basic] String

[C++] BSTR

OLE DB Type

DBTYPE_WSTR

Example

"ftp://ftp.Somewhere.microsoft.com"

© 2000-2001 Microsoft Corporation. All rights reserved.


gender Field

The gender of the contact.

Full Name

urn:schemas:contacts:gender

Content Class

urn:content-classes:person

Named Constant

CdoContacts.cdoGender

Variant SubType

[Visual Basic] Integer

[C++] Integer

OLE DB Type

DBTYPE_I2

Remarks

The values for this property are defined by the CdoGenderValues enumeration.

Example

cdoGenderUnspecified


givenname Field

The first name of the contact.

Full Name

urn:schemas:contacts:givenName

Content Class

urn:content-classes:person

Named Constant

CdoContacts.cdoFirstName

Variant SubType

[Visual Basic] String

[C++] BSTR

OLE DB Type

DBTYPE_WSTR

Remarks

This entry is also available as the IPerson::FirstName property.

Example

"Arlene"

© 2000-2001 Microsoft Corporation. All rights reserved.


governmentid Field

The government identifier, typically the social security number in the US, of the contact.

Full Name

urn:schemas:contacts:governmentid

Content Class

urn:content-classes:person

Named Constant

CdoContacts.cdoGovernmentId

Variant SubType

[Visual Basic] String

[C++] BSTR

OLE DB Type

DBTYPE_WSTR

Example

"000-111-2222”


hobbies Field

The hobbies of the contact.

Full Name

urn:schemas:contacts:hobbies

Content Class

urn:content-classes:person

Named Constant

CdoContacts.cdoHobbies

Variant SubType

[Visual Basic] String

[C++] BSTR

OLE DB Type

DBTYPE_WSTR

Remarks

The hobbies are separated by semicolons (;).

Example

"golf; skiing"

© 2000-2001 Microsoft Corporation. All rights reserved.


homecity Field

The home city of the contact.

Full Name

urn:schemas:contacts:homeCity

Content Class

urn:content-classes:person

Named Constant

CdoContacts.cdoHomeCity

Variant SubType

[Visual Basic] String

[C++] BSTR

OLE DB Type

DBTYPE_WSTR

Remarks

This entry is also available as the IPerson::HomeCity property.

Example

"Redmond"

© 2000-2001 Microsoft Corporation. All rights reserved.


homecountry Field

The home country/region of the contact.

Full Name

urn:schemas:contacts:homeCountry

Content Class

urn:content-classes:person

Named Constant

CdoContacts.cdoHomeCountry

Variant SubType

[Visual Basic] String

[C++] BSTR

OLE DB Type

DBTYPE_WSTR

Remarks

This entry is also available as the IPerson::HomeCountry property.

Example

"USA"

© 2000-2001 Microsoft Corporation. All rights reserved.


homefax Field

The home fax number of the contact.

Full Name

urn:schemas:contacts:homefax

Content Class

urn:content-classes:person

Named Constant

CdoContacts.cdoHomeFax

Variant SubType

[Visual Basic] Double

[C++] Double

OLE DB Type

DBTYPE_R8

Remarks

This entry is also available as the IPerson::HomeFax property.

Example

“111 111 1111”


homelatitude Field

The latitude of the home of the contact.

Full Name

urn:schemas:contacts:homelatitude

Content Class

urn:content-classes:person

Named Constant

CdoContacts.cdoHomeLatitude

Variant SubType

[Visual Basic] Double

[C++] Double

OLE DB Type

DBTYPE_R8

Example

47.6457


homelongitude Field

The longitude of the home of the contact.

Full Name

urn:schemas:contacts:homelongitude

Content Class

urn:content-classes:person

Named Constant

CdoContacts.cdoHomeLongitude

Variant SubType

[Visual Basic] Double

[C++] Double

OLE DB Type

DBTYPE_R8

Example

-122.1151


homephone Field

The home telephone number, in international dialing format, of the contact.

Full Name

urn:schemas:contacts:homePhone

Content Class

urn:content-classes:person

Named Constant

CdoContacts.cdoHomePhone

Variant SubType

[Visual Basic] String

[C++] BSTR

OLE DB Type

DBTYPE_WSTR

Remarks

This entry is also available as the IPerson::HomePhone property.

Example

"425-882-8080"


homephone2 Field

The alternative home telephone number, in international dialing format, of the contact.

Full Name

urn:schemas:contacts:homephone2

Content Class

urn:content-classes:person

Named Constant

CdoContacts.cdoHomePhone2

Variant SubType

[Visual Basic] String

[C++] BSTR

OLE DB Type

DBTYPE_WSTR

Example

"425-882-8080"


homepostaladdress Field

The home postal address of the contact.

Full Name

urn:schemas:contacts:homepostaladdress

Named Constant

CdoContacts.cdoHomePostalAddress

Variant SubType

[Visual Basic] String

[C++] BSTR

Read-only

OLE DB Type

DBTYPE_WSTR

Remarks

This entry is also available as the IPerson::HomePostalAddress property.

This field is constructed from the homestreet, homecity, homestate, and homepostalcode fields.


homepostalcode Field

The postal code, typically the zip code in the US, of the contact.

Full Name

urn:schemas:contacts:homepostalcode

Named Constant

CdoContacts.cdoHomePostalCode

Variant Subtype

[Visual Basic] String

[C++] BSTR

OLE DB Type

DBTYPE_WSTR

Remarks

This entry is also available as the IPerson::HomePostalCode property.

Example

"98052"


homepostofficebox Field

The post office box number of the contact.

Full Name

urn:schemas:contacts:homepostofficebox

Named Constant

CdoContacts.cdoHomePostOfficeBox

Variant Subtype

[Visual Basic] String

[C++] BSTR

OLE DB Type

DBTYPE_WSTR

Remarks

This entry is also available as the IPerson::HomePostOfficeBox property.

Example

"2345"


homestate Field

The home state of the contact.

Full Name

urn:schemas:contacts:homestate

Named Constant

CdoContacts.cdoHomeState

Variant Subtype

[Visual Basic] String

[C++] BSTR

OLE DB Type

DBTYPE_WSTR

Remarks

This entry is also available as the IPerson::HomeState property.

Example

"WA"

© 2000-2001 Microsoft Corporation. All rights reserved.


homestreet Field

The home street of the contact.

Full Name

urn:schemas:contacts:homestreet

Named Constant

CdoContacts.cdoHomeStreet

Variant Subtype

[Visual Basic] String

[C++] BSTR

OLE DB Type

DBTYPE_WSTR

Remarks

This entry is also available as the IPerson::HomeStreet property.

Example

"One Microsoft Way"

© 2000-2001 Microsoft Corporation. All rights reserved.


hometimezone field

The home time zone of the contact.

Full Name

urn:schemas:contacts:hometimezone

Named Constant

CdoContacts.cdoHomeTimeZone

Variant Subtype

[Visual Basic] String

[C++] BSTR

OLE DB Type

DBTYPE_WSTR

Example

"GMT + 8:00"

© 2000-2001 Microsoft Corporation. All rights reserved.


initials Field

The initials of the contact.

Full Name

urn:schemas:contacts:initials

Named Constant

CdoContacts.cdoInitials

Variant Subtype

[Visual Basic] String

[C++] BSTR

OLE DB Type

DBTYPE_WSTR

Remarks

This entry is also available as the IPerson::Initials property.

In CDO, the initials field is calculated from the capitalized first letters of the first, middle, last name. Each initial is separated by a period. The initials field has a maximum of six characters.

Note In Active Directory, the initials field represents the capitalized first letter of the middle name followed by a period. When a new user is created in Active Directory, the Initials field can be set to a string with a maximum of four characters.

Example

In CDO: "D.E.S."

In the DS: "E."

© 2000-2001 Microsoft Corporation. All rights reserved.


internationalisdnnumber Field

The ISDN number, in international dialing format, of the contact.

Full Name

urn:schemas:contacts:internationalisdnnumber

Named Constant

CdoContacts.cdoInternationalISDNNumber

Variant Subtype

[Visual Basic] String

[C++] BSTR

OLE DB Type

DBTYPE_WSTR

Example

"111 111 1111"


l Field

The city of the contact.

Full Name

urn:schemas:contacts:l

Named Constant

CdoContacts.cdoWorkCity

Variant Subtype

[Visual Basic] String

[C++] BSTR

OLE DB Type

DBTYPE_WSTR

Remarks

This entry is also available as the IPerson::WorkCity property.

Example

"Redmond"

© 2000-2001 Microsoft Corporation. All rights reserved.


language Field

The language, in ISO639 format, of the contact.

Full Name

urn:schemas:contacts:language

Named Constant

CdoContacts.cdoLanguage

Variant Subtype

[Visual Basic] String

[C++] BSTR

OLE DB Type

DBTYPE_WSTR

Example

"en"

© 2000-2001 Microsoft Corporation. All rights reserved.


location Field

Contains the contact's location.

Full Name

urn:schemas:contacts:location

Variant Subtype

[Visual Basic] String

[C++] BSTR

OLE DB Type

DBTYPE_WSTR

Example

"Southwest"

© 2000-2001 Microsoft Corporation. All rights reserved.


mailingaddressid Field

From which address entries the mailing address entries for the contact are constructed.

Full Name

urn:schemas:contacts:mailingaddressid

Named Constant

CdoContacts.cdoMailingAddressId

Variant Subtype

[Visual Basic] Long

[C++] Long

OLE DB Type

DBTYPE_UI4

Remarks

This entry is also available as the IPerson::MailingAddressID property.

Mailing entries are constructed from other contact entries, depending on the value of this entry. The values for this property are defined by the CdoMailingAddressIDValues enumeration.

Example

cdoBusinessAddress


mailingcity Field

The city portion of the mailing address for the contact.

Full Name

urn:schemas:contacts:mailingcity

Named Constant

CdoContacts.cdoMailingCity

Variant Subtype

[Visual Basic] String

[C++] BSTR

Read-only

OLE DB Type

DBTYPE_WSTR

Remarks

This entry is constructed from the city entry of another contact address, as specified by the mailingaddressid entry.

Example

"Redmond"

© 2000-2001 Microsoft Corporation. All rights reserved.


mailingcountry Field

The country/region portion of the mailing address for the contact.

Full Name

urn:schemas:contacts:mailingcountry

Named Constant

CdoContacts.cdoMailingCountry

Variant Subtype

[Visual Basic] String

[C++] BSTR

Read-only

OLE DB Type

DBTYPE_WSTR

Remarks

This entry is constructed from the country/region entry of another contact address, as specified by the mailingaddressid entry.

Example

"USA"

© 2000-2001 Microsoft Corporation. All rights reserved.


mailingpostaladdress Field

The postal address portion of the mailing address for the contact.

Full Name

urn:schemas:contacts:mailingpostaladdress

Named Constant

CdoContacts.cdoMailingPostalAddress

Variant Subtype

[Visual Basic] String

[C++] BSTR

Read-only

OLE DB Type

DBTYPE_WSTR

Remarks

This entry is also available as the IPerson::MailingAddress property.

This entry is constructed from the postal address entry of another contact address, as specified by the mailingaddressid entry.

Example

"One Microsoft Way Redmond, WA 98052"

© 2000-2001 Microsoft Corporation. All rights reserved.


mailingpostalcode Field

The postal code portion of the mailing address for the contact.

Full Name

urn:schemas:contacts:mailingpostalcode

Named Constant

CdoContacts.cdoMailingPostalCode

Variant Subtype

[Visual Basic] String

[C++] BSTR

Read-only

OLE DB Type

DBTYPE_WSTR

Remarks

This entry is constructed from the postal code entry of another contact address, as specified by the mailingaddressid entry.

Example

"98052"


mailingpostofficebox Field

The post office box portion of the mailing address for the contact.

Full Name

urn:schemas:contacts:mailingpostofficebox

Named Constant

CdoContacts.cdoMailingPostOfficeBox

Variant Subtype

[Visual Basic] String

[C++] BSTR

Read-only

OLE DB Type

DBTYPE_WSTR

Remarks

This entry is constructed from the post office box entry of another contact address, as specified by the mailingaddressid entry.

Example

"1234"


mailingstate Field

The state portion of the mailing address for the contact.

Full Name

urn:schemas:contacts:mailingstate

Named Constant

CdoContacts.cdoMailingState

Variant Subtype

[Visual Basic] String

[C++] BSTR

Read-only

OLE DB Type

DBTYPE_WSTR

Remarks

This entry is constructed from the state entry of another contact address, as specified by the mailingaddressid entry.

Example

"WA"

© 2000-2001 Microsoft Corporation. All rights reserved.


mailingstreet Field

The street portion of the mailing address for the contact.

Full Name

urn:schemas:contacts:mailingstreet

Named Constant

CdoContacts.cdoMailingStreet

Variant Subtype

[Visual Basic] String

[C++] BSTR

Read-only

OLE DB Type

DBTYPE_WSTR

Remarks

This entry is constructed from the street entry of another contact address, as specified by the mailingaddressid entry.

Example

"One Microsoft Way"

© 2000-2001 Microsoft Corporation. All rights reserved.


manager Field

The distinguished name (dn) for the contact’s manager.

Full Name

urn:schemas:contacts:manager

Named Constant

CdoContacts.cdoManager

Variant Subtype

[Visual Basic] String

[C++] BSTR

OLE DB Type

DBTYPE_WSTR

Example

"cn=Fred, cn=users, dc=subdomain, dc=somewhere, dc=microsoft, dc=com"


mapurl Field

The map URL for the contact.

Full Name

urn:schemas:contacts:mapurl

Named Constant

CdoContacts.cdoMapURL

Variant Subtype

[Visual Basic] String

[C++] BSTR

Read-only

OLE DB Type

DBTYPE_WSTR

Example

"http://www.microsoft.com?sdfdsfds=5336, dsfdfsd=553"


members Field

The members of a group contact.

Full Name

urn:schemas:contacts:members

Named Constant

CdoContacts.cdoMembers

Variant Subtype

[Visual Basic] Safearray of Strings

[C++] BSTR[]

OLE DB Type

DBTYPE_VECTOR (of WSTR)

Remarks

Reserved for future use.

Example

Reserved for future use.


middlename Field

The middle name of the contact.

Full Name

urn:schemas:contacts:middlename

Named Constant

CdoContacts.cdoMiddleName

Variant Subtype

[Visual Basic] String

[C++] BSTR

OLE DB Type

DBTYPE_WSTR

Remarks

This entry is also available as the IPerson::MiddleName property.

Example

"Angela"

© 2000-2001 Microsoft Corporation. All rights reserved.


mobile Field

The mobile telephone number, in international dialing format, of the contact.

Full Name

urn:schemas:contacts:mobile

Named Constant

CdoContacts.cdoWorkMobilePhone

Variant Subtype

[Visual Basic] String

[C++] BSTR

OLE DB Type

DBTYPE_WSTR

Example

"111 111 1111"


namesuffix Field

The generation qualifier for the contact.

Full Name

urn:schemas:contacts:namesuffix

Named Constant

CdoContacts.cdoNameSuffix

Variant Subtype

[Visual Basic] String

[C++] BSTR

OLE DB Type

DBTYPE_WSTR

Example

“Jr.” or “Esquire”

© 2000-2001 Microsoft Corporation. All rights reserved.


nickname Field

The nickname of the contact.

Full Name

urn:schemas:contacts:nickname

Named Constant

CdoContacts.cdoNickname

Variant Subtype

[Visual Basic] String

[C++] BSTR

OLE DB Type

DBTYPE_WSTR

Example

"Tony"

© 2000-2001 Microsoft Corporation. All rights reserved.


o Field

The name of the organization or company for the contact.

Full Name

urn:schemas:contacts:o

Named Constant

CdoContacts.cdoOrganizationName

Variant Subtype

[Visual Basic] String

[C++] BSTR

OLE DB Type

DBTYPE_WSTR

Example

"Microsoft"

© 2000-2001 Microsoft Corporation. All rights reserved.


office2telephonenumber Field_

Platform SDK: Exchange 2000 Server

office2telephonenumber Field

The secondary office phone number.

Full Name

urn:schemas:contacts:office2telephonenumber

Variant Subtype

[Visual Basic] String

[C++] BSTR

OLE DB Type

DBTYPE_WSTR

Example

"111 111 1111"


officetelephonenumber Field

The primary office phone number.

Full Name

urn:schemas:contacts:officetelephonenumber

Variant Subtype

[Visual Basic] String

[C++] BSTR

OLE DB Type

DBTYPE_WSTR

Example

"111 111 1111"


organizationmainphone Field

The main telephone number for a company.

Full Name

urn:schemas:contacts:organizationmainphone

Variant Subtype

[Visual Basic] String

[C++] BSTR

OLE DB Type

DBTYPE_WSTR

Example

"111 111 1111"


othercity Field

The alternative city for the contact.

Full Name

urn:schemas:contacts:othercity

Named Constant

CdoContacts.cdoOtherCity

Variant Subtype

[Visual Basic] String

[C++] BSTR

OLE DB Type

DBTYPE_WSTR

Example

"Redmond"

© 2000-2001 Microsoft Corporation. All rights reserved.


othercountry Field

The alternative country/region for the contact.

Full Name

urn:schemas:contacts:othercountry

Named Constant

CdoContacts.cdoOtherCountry

Variant Subtype

[Visual Basic] String

[C++] BSTR

OLE DB Type

DBTYPE_WSTR

Example

"Canada"

© 2000-2001 Microsoft Corporation. All rights reserved.


othercountrycode Field

The alternative two-letter country/region code for the contact.

Full Name

urn:schemas:contacts:othercountrycode

Named Constant

CdoContacts.cdoOthercountryCode

Variant Subtype

[Visual Basic] String

[C++] BSTR

OLE DB Type

DBTYPE_WSTR

Example

"Ca"

© 2000-2001 Microsoft Corporation. All rights reserved.


otherfax Field

The alternative work-FAX number, in international dialing format, for a contact.

Full Name

urn:schemas:contacts:otherfax

Named Constant

CdoContacts.OtherFax

Variant Subtype

[Visual Basic] String

[C++] BSTR

OLE DB Type

DBTYPE_WSTR

Example

"111 111 1111"


othermobile Field

The alternative mobile telephone number, in international dialing format, of the contact.

Full Name

urn:schemas:contacts:othermobile

Named Constant

CdoContacts.cdoOtherMobile

Variant Subtype

[Visual Basic] String

[C++] BSTR

OLE DB Type

DBTYPE_WSTR

Example

"111 111 1111"


otherpager Field

The alternative pager telephone number, in international dialing format, of the contact.

Full Name

urn:schemas:contacts:otherpager

Named Constant

CdoContacts.cdoWorkPager

Variant Subtype

[Visual Basic] String

[C++] BSTR

OLE DB Type

DBTYPE_WSTR

Example

"111 111 1111"


otherpostaladdress Field

The alternative postal address for the contact.

Full Name

urn:schemas:contacts:otherpostaladdress

Named Constant

CdoContacts.cdoOtherPostalAddress

Variant Subtype

[Visual Basic] String

[C++] BSTR

Read-only

OLE DB Type

DBTYPE_WSTR

Remarks

This entry is constructed.

Example

"One Microsoft Way"

© 2000-2001 Microsoft Corporation. All rights reserved.


otherpostalcode Field

The alternative postal code, typically a zip code in the US, for the contact.

Full Name

urn:schemas:contacts:otherpostalcode

Named Constant

CdoContacts.cdoOtherPostalCode

Variant Subtype

[Visual Basic] String

[C++] BSTR

OLE DB Type

DBTYPE_WSTR

Example

"98052"


otherpostofficebox Field

The alternative post office box for the contact.

Full Name

urn:schemas:contacts:otherpostofficebox

Named Constant

CdoContacts.cdoOtherPostOfficeBox

Variant Subtype

[Visual Basic] String

[C++] BSTR

OLE DB Type

DBTYPE_WSTR

Example

"1234"


otherstate Field

The alternative state, province, or parish, for the contact.

Full Name

urn:schemas:contacts:otherstate

Named Constant

CdoContacts.cdoOtherState

Variant Subtype

[Visual Basic] String

[C++] BSTR

OLE DB Type

DBTYPE_WSTR

Example

"WA"

© 2000-2001 Microsoft Corporation. All rights reserved.


otherstreet Field

The alternative work street address of the contact.

Full Name

urn:schemas:contacts:otherstreet

Named Constant

CdoContacts.cdoOtherStreet

Variant Subtype

[Visual Basic] String

[C++] BSTR

OLE DB Type

DBTYPE_WSTR

Example

"One Microsoft Way"

© 2000-2001 Microsoft Corporation. All rights reserved.


othertelephone Field

The alternative work telephone, in international dialing format, of the contact.

Full Name

urn:schemas:contacts:othertelephone

Named Constant

CdoContacts.cdoOtherWorkPhone

Variant Subtype

[Visual Basic] String

[C++] BSTR

OLE DB Type

DBTYPE_WSTR

Example

"111 111 1111"


othertimezone Field

The alternative work time zone for the contact.

Full Name

urn:schemas:contacts:othertimezone

Named Constant

CdoContacts.cdoOtherTimeZone

Variant Subtype

[Visual Basic] String

[C++] BSTR

OLE DB Type

DBTYPE_WSTR

Example

"PDT"

© 2000-2001 Microsoft Corporation. All rights reserved.


pager Field

The work pager telephone number, in international dialing format, of the contact.

Full Name

urn:schemas:contacts:pager

Named Constant

CdoContacts.cdoPager

Variant Subtype

[Visual Basic] String

[C++] BSTR

OLE DB Type

DBTYPE_WSTR

Example

"111 111 1111"


personalhomepage Field

The URL of the home page for the contact.

Full Name

urn:schemas:contacts:personalhomepage

Named Constant

CdoContacts.cdoPersonalURL

Variant Subtype

[Visual Basic] String

[C++] BSTR

OLE DB Type

DBTYPE_WSTR

Example

"http://www.Somewhere.microsoft.com"

© 2000-2001 Microsoft Corporation. All rights reserved.


personaltitle Field

The prefix title for the contact.

Full Name

urn:schemas:contacts:personaltitle

Named Constant

CdoContacts.cdoNamePrefix

Variant Subtype

[Visual Basic] String

[C++] BSTR

OLE DB Type

DBTYPE_WSTR

Example

"Ms."

© 2000-2001 Microsoft Corporation. All rights reserved.


postalcode Field

The work postal code, typically the zip code in the US, for the contact.

Full Name

urn:schemas:contacts:postalcode

Named Constant

CdoContacts.cdoWorkPostalCode

Variant Subtype

[Visual Basic] String

[C++] BSTR

OLE DB Type

DBTYPE_WSTR

Remarks

This entry is also available as the IPerson::WorkPostalCode property.

Example

"98052"


postofficebox Field

The work post office box number of the contact.

Full Name

urn:schemas:contacts:postofficebox

Named Constant

CdoContacts.cdoWorkPostOfficeBox

Variant Subtype

[Visual Basic] String

[C++] BSTR

OLE DB Type

DBTYPE_WSTR

Remarks

This entry is also available as the IPerson::WorkPostOfficeBox property.

Example

"1234"


profession Field

The profession of the contact.

Full Name

urn:schemas:contacts:profession

Named Constant

CdoContacts.cdoProfession

Variant Subtype

[Visual Basic] String

[C++] BSTR

OLE DB Type

DBTYPE_WSTR

Example

"Software engineer"

© 2000-2001 Microsoft Corporation. All rights reserved.


proxyaddresses Field

A multi-valued property containing one or more client e-mail addresses.

Full Name

urn:schemas:contacts:proxyaddresses

Named Constant

CdoContacts.cdoProxyAddresses

Variant SubType

[Visual Basic] Variant

[C++] VT_ARRAY | VT_BSTR

OLE DB Type

DBTYPE_VECTOR | DBTYPE_WSTR

Remarks

This entry is also available as the IPerson::EmailAddresses property.

The address should comply with the RFC 822 address format.

Example

"someone@microsoft.com"

© 2000-2001 Microsoft Corporation. All rights reserved.


referredby Field

The full name of the person who referred the contact.

Full Name

urn:schemas:contacts:referredby

Variant Subtype

[Visual Basic] String

[C++] BSTR

OLE DB Type

DBTYPE_WSTR

Example

"John Smith"

© 2000-2001 Microsoft Corporation. All rights reserved.


roomnumber Field

The room number for the contact.

Full Name

urn:schemas:contacts:roomnumber

Named Constant

CdoContacts.cdoRoomNumber

Variant Subtype

[Visual Basic] String

[C++] BSTR

OLE DB Type

DBTYPE_WSTR

Example

"20"


secretary Field

The full name of the secretary for the contact.

Full Name

urn:schemas:contacts:secretary

Named Constant

CdoContacts.cdoSecretary

Variant Subtype

[Visual Basic] String

[C++] BSTR

OLE DB Type

DBTYPE_WSTR

Example

"Susan M Tjarnberg"

© 2000-2001 Microsoft Corporation. All rights reserved.


secretarycn Field

The common (or friendly) name of the secretary for the contact.

Full Name

urn:schemas:contacts:secretarycn

Named Constant

CdoContacts.cdoSecretaryCommonName

Variant Subtype

[Visual Basic] String

[C++] BSTR

OLE DB Type

DBTYPE_WSTR

Example

"Sean"

© 2000-2001 Microsoft Corporation. All rights reserved.


secretaryphone Field

The phone number for the contact’s secretary.

Full Name

urn:schemas:contacts:secretaryphone

Variant Subtype

[Visual Basic] String

[C++] BSTR

OLE DB Type

DBTYPE_WSTR

Example

"111 111 1111"


secretaryurl Field

The URL to the secretary for the contact.

Full Name

urn:schemas:contacts:secretaryurl

Named Constant

CdoContacts.cdoSecretaryURL

Variant Subtype

[Visual Basic] String

[C++] BSTR

OLE DB Type

DBTYPE_WSTR

Example

"http://Somewhere.microsoft.com/seanchai"


sn Field

The surname of the contact.

Full Name

urn:schemas:contacts:sn

Named Constant

CdoContacts.cdoLastName

Variant Subtype

[Visual Basic] String

[C++] BSTR

OLE DB Type

DBTYPE_WSTR

Remarks

This entry is also available as the IPerson::LastName property.

Example

"Nagata"

© 2000-2001 Microsoft Corporation. All rights reserved.


sourceurl Field

The URL to the source for the contact.

Full Name

urn:schemas:contacts:sourceurl

Named Constant

CdoContacts.cdoSourceURL

Variant Subtype

[Visual Basic] String

[C++] BSTR

OLE DB Type

DBTYPE_WSTR

Example

"http://Somewhere.microsoft.com/suannenagata"


spousecn Field

The friendly name of the spouse for the contact.

Full Name

urn:schemas:contacts:spousecn

Named Constant

CdoContacts.cdoSpouseCommonName

Variant Subtype

[Visual Basic] String

[C++] BSTR

OLE DB Type

DBTYPE_WSTR

Example

"Rick"

© 2000-2001 Microsoft Corporation. All rights reserved.


st Field

The work state for the contact.

Full Name

urn:schemas:contacts:st

Named Constant

CdoContacts.cdoWorkState

Variant Subtype

[Visual Basic] String

[C++] BSTR

OLE DB Type

DBTYPE_WSTR

Remarks

This entry is also available as the IPerson::WorkState property.

Example

"WA"

© 2000-2001 Microsoft Corporation. All rights reserved.


street Field

The contact's work address.

Full Name

urn:schemas:contacts:street

Named Constant

CdoContacts.cdoWorkStreet

Variant Subtype

[Visual Basic] String

[C++] BSTR

OLE DB Type

DBTYPE_WSTR

Remarks

This entry is also available as the IPerson::WorkStreet property.

Example

"One Microsoft Way"

© 2000-2001 Microsoft Corporation. All rights reserved.


submissioncontlength Field

The maximum length, in kilobytes (KB), of a message that can be sent to the contact.

Full Name

urn:schemas:contacts:submissioncontlength

Named Constant

CdoContacts.cdoSubmissionContLength

Variant Subtype

[Visual Basic] Long

[C++] long

OLE DB Type

DBTYPE_WSTR

Example

"80"


telephonenumber Field

The work telephone number, in international dialing format, of the contact.

Full Name

urn:schemas:contacts:telephonenumber

Named Constant

CdoContacts.cdoWorkPhone

Variant Subtype

[Visual Basic] String

[C++] BSTR

OLE DB Type

DBTYPE_WSTR

Remarks

This entry is also available as the IPerson::WorkPhone property.

Example

"111 111 1111"


telephonenumber2 Field

The alternative work telephone number, in international dialing format, of the contact.

Full Name

urn:schemas:contacts:telephonenumber2

Named Constant

CdoContacts.cdoWorkPhone2

Variant Subtype

[Visual Basic] String

[C++] BSTR

OLE DB Type

DBTYPE_WSTR

Example

"111 111 1111"


telexnumber Field

The work telex number for the contact in international dialing format.

Full Name

urn:schemas:contacts:telexnumber

Named Constant

CdoContacts.cdoTelexNumber

Variant Subtype

[Visual Basic] String

[C++] BSTR

OLE DB Type

DBTYPE_WSTR

Example

"111 111 1111"


title Field

The work title or job position of the contact.

Full Name

urn:schemas:contacts:title

Named Constant

CdoContacts.cdoTitle

Variant Subtype

[Visual Basic] String

[C++] BSTR

OLE DB Type

DBTYPE_WSTR

Remarks

This entry is also available as the IPerson::Title property.

Example

Vice President of Marketing

© 2000-2001 Microsoft Corporation. All rights reserved.


ttytddphone Field

The ttytdd phone number.

Full Name

urn:schemas:contacts:ttytddphone

Variant Subtype

[Visual Basic] String

[C++] BSTR

OLE DB Type

DBTYPE_WSTR

Example

"111 111 1111"


unauthorig Field

Contains e-mail addresses that cannot send messages to this e-mail address.

Full Name

urn:schemas:contacts:unauthorig

Named Constant

Reserved for future use.

Variant Subtype

[Visual Basic] String

[C++] BSTR

OLE DB Type

VECTOR WSTR

Example

someone@someplace.microsoft.com


usercertificate Field

The certificate used to authenticate the contact.

Full Name

urn:schemas:contacts:usercertificate

Named Constant

CdoContacts.cdoUserCertificate

Variant Subtype

[Visual Basic] BYTES

[C++] char[]

OLE DB Type

DBTYPE_BYTES

© 2000-2001 Microsoft Corporation. All rights reserved.


weddinganniversary Field

The wedding anniversary of the contact.

Full Name

urn:schemas:contacts:weddinganniversary

Named Constant

CdoContacts.cdoWeddingAnniversary

Variant Subtype

[Visual Basic] Date

[C++] DATE

OLE DB Type

DBTYPE_DBDATE

Example

#10/18/1984#


workaddress Field

The work address for the contact.

Full Name

urn:schemas:contacts:workaddress

Named Constant

CdoContacts.cdoWorkAddress

Variant Subtype

[Visual Basic] String

[C++] BSTR

Read-only

OLE DB Type

DBTYPE_WSTR

Remarks

This entry is constructed from other contact entries.


urn:schemas:httpmail: Namespace

The urn:schemas:httpmail: namespace, similar to the urn:schemas:mailheader: namespace, defines core properties for messages. However, within this namespace, string fields are returned with all characters that were encoded per Requests for Comments (RFC) 1522 decoded into UNICODE characters. This namespace also contains additional fields not found in urn:schemas:mailheader: that are routinely used to render messaging information to clients through a Web browser or user agent. The following properties have counterparts in the urn:schemas:mailheader: namespace.

bcc

cc

date

datereceived

from

importance

priority

reply-to

sender

to

The following properties identify the URIs to a particular user's mailbox folders, and the Microsoft® Exchange mail transmission URI:

msgfolderroot (root mailbox folder)

calendar

contacts

deleteditems

drafts

inbox

journal

notes

outbox

tasks

sentitems

sendmsg (Exchange mail transmission URI)

Use these fields to render messaging information within Web browsers or user agents (UAs), especially when characters within the various message headers are not US-ASCII, or when you are unsure what character sets to expect. All fields within the urn:schemas:mailheader: namespace are always returned as US-ASCII characters, with any non US-ASCII characters encoded using the mechanism described in RFC 1522.


attachmentfilename Field

The name of the attached file.

Full Name

urn:schemas:httpmail:attachmentfilename

Named Constant

CdoHTTPMail.cdoAttachmentFilename

OLE DB Type

DBTYPE_WSTR

Read-Only

Variant SubType

[Visual Basic] String

[C++] BSTR

Read-Only

Remarks

Corresponds to the filename: parameter of the Content-Disposition mail header when its value is "attachment." To change this value, change the urn:schemas:mailheader:content-disposition header field.

Example

myimage.gif

See Also

urn:schemas:mailheader:content-disposition Field


bcc Field

The blind carbon copy (BCC) recipients for the message.

Full Name

urn:schemas:httpmail:bcc

Content Class

urn:content-classes:message

Named Constant

cdoHTTPMail.cdoBcc

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Remarks

This field differs from the urn:schemas:mailheader:bcc field only in that all RFC 1522 encoded characters are decoded and returned as UNICODE characters.

Example

"Some One" <someone@microsoft.com>

See Also

urn:schemas:mailheader:bcc Field


calendar Field

Read-only. The URL to a user's calendar folder.

Full Name

urn:schemas:httpmail:calendar

Named Constant

cdoHTTPMail.cdoHTTPMailCalendar

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Remarks

This field is set on a user's root mailbox folder to identify the URL to their Calendar folder, and on a contact item identifying that contact's Calendar folder.

Example

file://./backofficestorage/<domain>/MBX/<username>/Calendar


cc Field

The carbon copy (CC) recipients of the message.

Full Name

urn:schemas:httpmail:cc

Content Class

urn:content-classes:message

Named Constant

cdoHTTPMail.cdoCc

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Remarks

This field differs from the urn:schemas:mailheader:cc field only in that all RFC 1522 encoded characters are decoded and returned as UNICODE characters.

Example

"Some User" <someuser@microsoft.com>, "Another User" <anotheruser@microsoft.com>

See Also

urn:schemas:mailheader:cc Field


contacts Field

Read-only. The URL to the user's contacts folder.

Full Name

urn:schemas:httpmail:contacts

Named Constant

cdoHTTPMail.cdoHTTPMailContacts

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Remarks

This field is set on a user's root mailbox folder to identify the URL to their contacts folder.

Example

http://server.microsoft.com/exchange/UserAlias/Contacts


content-disposition-type Field

The type portion of the Content-Disposition MIME header for a body part. Valid values include unspecified, other, attachment, and inline.

Full Name

urn:schemas:httpmail:content-disposition-type

Content Class

urn:content-classes:message

Named Constant

cdoHTTPMail.cdoContentDispositionType

OLE DB Type

DBTYPE_WSTR

Variant SubType

[Visual Basic] String

[C++] BSTR

Example

"inline"

"attachment"

See Also

urn:schemas:mailheader:content-disposition Field


content-media-type Field

The content media type for the body part.

Full Name

urn:schemas:httpmail:content-media-type

Content Class

urn:content-classes:message

Named Constant

CdoHTTPMail.cdoContentMediaType

OLE DB Type

DBTYPE_WSTR

Variant SubType

[Visual Basic] String

[C++] BSTR

Remarks

This field corresponds to the content media type of the Content-Type RFC 1522 header.

The following string constants are provided in the CDO type library:

CdoContentTypeValues Module Constants

Constant | Value | Description
cdoGif | "image/gif" | Image encoded using Graphics Interchange Format (GIF)
cdoJpeg | "image/jpeg" | Image encoded using Joint Photographic Experts Group format (ISO/IEC 10918)
cdoMessageExternalBody | "message/external-body" | Pointer to message content outside this message
cdoMessagePartial | "message/partial" | One piece of a fragmented message
cdoMessageRFC822 | "message/rfc822" | Simple e-mail message, not even a forward
cdoMultipartAlternative | "multipart/alternative" | Different versions of same content, simplest first
cdoMultipartDigest | "multipart/digest" | Different messages, including forwarded messages
cdoMultipartMixed | "multipart/mixed" | Body parts to be processed sequentially
cdoMultipartRelated | "multipart/related" | Body parts accessed through URLs
cdoTextHtml | "text/html" | Text with HTML tags
cdoTextPlain | "text/plain" | Unstructured text

Example

text/plain

See Also

urn:schemas:mailheader:content-type Field


date Field

The date and time on which the message was sent.

Full Name

urn:schemas:httpmail:date

Content Class

urn:content-classes:message

Named Constant

cdoHTTPMail.cdoDate

OLE DB Type

DBTYPE_FILETIME

Variant Subtype

[Visual Basic] Date

[C++] DATE (VT_DATE)

Remarks

This field is identical to the urn:schemas:mailheader:date field.

See Also

urn:schemas:mailheader:date Field


datereceived Field

The date and time that the message was received by the server.

Full Name

urn:schemas:httpmail:datereceived

Named Constant

CdoHTTPMail.cdoDateReceived

OLE DB Type

DBTYPE_DBTIMESTAMP

Read-Only

Variant SubType

[Visual Basic] Date

[C++] DATE (VT_DATE)

Read-Only

Remarks

This value is computed from the first (most recent) received header in the message.

Example

10/5/98 11:52 AM

© 2000-2001 Microsoft Corporation. All rights reserved.


deleteditems Field

Read-only. The URL to a user's Deleted Items folder.

Full Name

urn:schemas:httpmail:deleteditems

Named Constant

cdoHTTPMail.cdoHTTPMailDeletedItems

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Remarks

This field is set on a user's root mailbox folder to identify the URL to their Deleted Items folder.

Example

http://server.microsoft.com/exchange/UserAlias/Deleted%20Items


displaybcc Field

Read-only. The display names of the blind carbon copy recipients of the message.

Full Name

urn:schemas:httpmail:displaybcc

Content Class

urn:content-classes:message

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Remarks

This property returns only the display names for message bcc recipients.

Example

User 1 (Exchange)


displaycc Field

Read-only. The display names of the carbon copy recipients of a message.

Full Name

urn:schemas:httpmail:displaycc

Content Class

urn:content-classes:message

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Example

User 1 (Exchange)


displayto Field

Read-only. The display names of the primary (To) recipients of the message.

Full Name

urn:schemas:httpmail:displayto

Content Class

urn:content-classes:message

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Example

User 1 (Exchange)


drafts Field

Read-only. The URL to a user's Drafts folder.

Full Name

urn:schemas:httpmail:drafts

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Remarks

This field is set on a user's root mailbox folder to identify the URL to their Drafts folder.

Example

http://server.microsoft.com/exchange/UserAlias/Drafts


expiry-date Field

An item's expiration date.

Full Name

urn:schemas:httpmail:expiry-date

Content Class

urn:content-classes:item

OLE DB Type

DBTYPE_DBFILETIME

Variant Subtype

[Visual Basic] Date

[C++] DATE

Example

#3/19/99 3:12:00 PM#

© 2000-2001 Microsoft Corporation. All rights reserved.


flagcompleted Field

The date and time a message item was flagged as completed.

Full Name

urn:schemas:httpmail:flagcompleted

Content Class

urn:content-classes:message

OLE DB Type

DBTYPE_DBTIMESTAMP

Variant Subtype

[Visual Basic] Date

[C++] DATE

Remarks

The value of this property can be defined by the X-Message-Completed mail header field for a message.

Example

#3/19/99 3:12:00 PM#

© 2000-2001 Microsoft Corporation. All rights reserved.


from Field

The addressees from whom the message was sent.

Full Name

urn:schemas:httpmail:from

Content Class

urn:content-classes:message

Named Constant

cdoHTTPMail.cdoFrom

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Remarks

This field differs from the urn:schemas:mailheader:from field only in that all RFC 1522 encoded characters are decoded and returned as UNICODE characters.

Example

"Some User" <someuser@microsoft.com>, "Another User" <anotheruser@microsoft.com>

See Also

urn:schemas:mailheader:from Field


fromemail Field

Read-only. The e-mail address from which the message was sent.

Full Name

urn:schemas:httpmail:fromemail

Content Class

urn:content-classes:message

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Example

user@microsoft.com

See Also

fromname Field, from Field


fromname Field

Read-only. The display name of the user or entity from which the message was sent.

Full Name

urn:schemas:httpmail:fromname

Content Class

urn:content-classes:message

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Example

User 1

See Also

fromemail Field, from Field


hasattachment Field

Read-only. Indicates whether or not the message has attachments.

Full Name

urn:schemas:httpmail:hasattachment

Content Class

urn:content-classes:appointment

urn:content-classes:message

Named Constant

CdoHTTPMail.cdoHasAttachment

OLE DB Type

DBTYPE_BOOL

Variant SubType

[Visual Basic] Boolean

[C++] VARIANT_BOOL (VT_BOOL)

Example

True

© 2000-2001 Microsoft Corporation. All rights reserved.


htmldescription Field

The HTML content of the message.

Full Name

urn:schemas:httpmail:htmldescription

Content Class

urn:content-classes:appointment

urn:content-classes:message

Named Constant

CdoHTTPMail.cdoHTMLDescription

OLE DB Type

DBTYPE_WSTR

Variant SubType

[Visual Basic] String

[C++] BSTR

Example

<!DOCTYPE HTML PUBLIC "-//W3C//DTD W3 HTML//EN"> <HTML><HEAD>…


importance Field

The message's importance.

Full Name

urn:schemas:httpmail:importance

Content Class

urn:content-classes:message

Named Constant

cdoHTTPMail.cdoImportance

OLE DB Type

DBTYPE_I4

Variant Subtype

[Visual Basic] Long

[C++] long (VT_I4)

Remarks

The value for this field is one of the enumeration values defined by the CdoImportanceValues enumeration.

Example

-1

See Also

CdoImportanceValues enumeration

© 2000-2001 Microsoft Corporation. All rights reserved.


inbox Field

Read-only. The URL to a user's Inbox folder.

Full Name

urn:schemas:httpmail:inbox

Named Constant

CdoHTTPMail.cdoInbox

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Remarks

This field is set on a user's root mailbox folder to identify the URL to their Inbox folder.

Example

http://server.microsoft.com/exchange/UserAlias/Inbox


journal Field

Read-only. The URL to a user's Journal folder.

Full Name

urn:schemas:httpmail:journal

Named Constant

CdoHTTPMail.cdoJournal

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Remarks

This field is set on a user's root mailbox folder to identify the URL to their Journal folder.

Example

http://server.microsoft.com/exchange/UserAlias/Journal


messageflag Field

The message flag value for the message.

Full Name

urn:schemas:httpmail:messageflag

Content Class

urn:content-classes:message

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Remarks

This field is equivalent to the X-Message-Flag mail header field. However, all RFC 1522 encoded characters are returned as decoded, UNICODE characters.

Example

followup, read by


msgfolderroot Field

Read-only. The URL to a user's mailbox folder root.

Full Name

urn:schemas:httpmail:msgfolderroot

Named Constant

CdoHTTPMail.cdoMsgFolderRoot

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Example

file://./backofficestorage/<domain>/MBX/<username>/


normalizedsubject Field

Read-only. Subject text string with all prefixes such as "Re:" and "Fwd:" removed.

Full Name

urn:schemas:httpmail:normalizedsubject

Content Class

urn:content-classes:appointment

urn:content-classes:message

Named Constant

cdoHTTPMail.cdoNormalizedSubject

OLE DB Type

DBTYPE_WSTR

Variant SubType

[Visual Basic] String

[C++] BSTR

Remarks

This value can be used for sorting by subject or for applying a new prefix on forward or reply actions. By adding the new prefix to the normalized subject value, you can avoid message subjects such as "Re: Re:Staff meeting agenda."

Example

Staff meeting agenda

See Also

urn:schemas:mailheader:subject Field

urn:schemas:httpmail:subject Field


notes Field

Read-only. The URL to a user's Notes folder.

Full Name

urn:schemas:httpmail:notes

Named Constant

CdoHTTPMail.cdoNotes

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Remarks

This field is set on a user's root mailbox folder to identify the URL to their Notes folder.

Example

http://server.microsoft.com/exchange/UserAlias/Notes


outbox Field

Read-only. The URL to a user's Outbox folder.

Full Name

urn:schemas:httpmail:outbox

Named Constant

CdoHTTPMail.cdoOutbox

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Remarks

This field is set on a user's root mailbox folder to identify the URL to their Outbox folder.

Example

http://server.microsoft.com/exchange/UserAlias/Outbox


priority Field

The message's priority.

Full Name

urn:schemas:httpmail:priority

Content Class

urn:content-classes:appointment

urn:content-classes:message

Named Constant

cdoHTTPMail.cdoPriority

OLE DB Type

DBTYPE_I4

Variant Subtype

[Visual Basic] Long

[C++] long

Remarks

The value for this field is one of the enumeration values defined by the CdoPriorityValues enumeration.

Example

-1

See Also

CdoPriorityValues Enum

© 2000-2001 Microsoft Corporation. All rights reserved.


read Field

Indicates whether the message has been read.

Full Name

urn:schemas:httpmail:read

Content Class

urn:content-classes:item

OLE DB Type

DBTYPE_BOOL

Variant Subtype

[Visual Basic] Boolean

[C++] VARIANT_BOOL

Example

True

© 2000-2001 Microsoft Corporation. All rights reserved.


reply-by Field

Indicates whether the message has been read.

Full Name

urn:schemas:httpmail:reply-by

Content Class

urn:content-classes:message

OLE DB Type

DBTYPE_DBFILETIME

Variant Subtype

[Visual Basic] Date

[C++] DATE

Remarks

This field is equivalent to the urn:schemas:mailheader:reply-by header field. The value, however, is returned in the Date format rather than an ASCII string.

Example

#3/19/99 12:25:00 PM#

© 2000-2001 Microsoft Corporation. All rights reserved.


reply-to Field

The recipients to whom replies should be sent.

Full Name

urn:schemas:httpmail:reply-to

Content Class

urn:content-classes:message

Named Constant

CdoHTTPMail.cdoReplyTo

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Remarks

This field differs from the urn:schemas:mailheader:reply-to field only in that all RFC 1522 encoded characters are decoded and returned as UNICODE characters.

Example

"John Fortune" <john@widgets-inc.widgets.com>

See Also

urn:schemas:mailheader:reply-to Field

IMessage.ReplyTo

© 2000-2001 Microsoft Corporation. All rights reserved.


savedestination Field

Where the item should be saved after it is transmitted using the Microsoft® Exchange 2000 Server mail transmission URI.

Full Name

urn:schemas:httpmail:savedestination

Content Class

urn:content-classes:message

Named Constant

None

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Remarks

Specify the URL to the folder in which to save this item after it has been transmitted using the Exchange mail transmission URI, either through the Web Storage System OLE DB provider, or with the WebDAV protocol. If this property is not set, and you have set the urn:schemas:httpmail:saveinsent property to True, the message is saved in the user's standard Saved Items folder.

When transmitting a message using the WebDAV POST or PUT protocol commands, the value specified by a SAVEDESTINATION: HTTP header, if transmitted, takes precedence over the value of this property.

Example

http://server.microsoft.com/exchange/user1/special_save_folder/

See Also

urn:schemas:httpmail:saveinsent, urn:schemas:httpmail:sendmsg


saveinsent Field

Specifies whether the item should be saved in the Sent Items folder after it is transmitted using the Exchange mail transmission URI, through either the Web Storage System OLE DB provider or the WebDAV protocol.

Full Name

urn:schemas:httpmail:saveinsent

Content Class

urn:content-classes:message

Named Constant

None

OLE DB Type

DBTYPE_BOOL

Variant Subtype

[Visual Basic] Boolean

[C++] VARIANT_BOOL

Remarks

Use this property to indicate that a message is to be saved after being sent using the WebDAV protocol and the Microsoft® Exchange 2000 Server mail submission URI. By default, the message will be stored in the user's Sent Items folder. To specify an alternate folder, use the urn:schemas:httpmail:savedestination property.

Both the urn:schemas:httpmail:saveinsent and urn:schemas:httpmail:savedestination properties have equivalent WebDAV headers: SAVEINSENT: and SAVEDESTINATION: respectively. If present, these headers override the values of these properties.

Example

True

See Also

urn:schemas:httpmail:savedestination, urn:schemas:httpmail:sendmsg


sender Field

Indicates the actual message sender, if different than the From: field. This field corresponds to the RFC 822 Sender: header for a message.

Full Name

urn:schemas:httpmail:sender

Content Class

urn:content-classes:message

Named Constant

CdoMailHeader.cdoSender

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Remarks

This field corresponds to the Sender header field of RFC 822.

This field differs from the urn:schemas:mailheader:subject field only in that all RFC 1522 encoded characters are decoded and returned as UNICODE characters.

Example

"John Kelly" <johnkelly@microsoft.com>

See Also

sendername Field, senderemail Field, IMessage.Sender


senderemail Field

The e-mail address of the message sender.

Full Name

urn:schemas:httpmail:senderemail

Content Class

urn:content-classes:message

Named Constant

None

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Remarks

This field corresponds to the Sender header field of RFC 822.

This field differs from the urn:schemas:httpmail:sender field in that only the e-mail portion of the address is returned. Additionally, all RFC 1522 encoded characters are decoded and returned as UNICODE characters.

Example

jdoe@microsoft.com

See Also

sendername Field, sender Field, IMessage.Sender


sendername Field

The display name of the message sender. This field corresponds to the RFC 822 Sender: header for a message.

Full Name

urn:schemas:httpmail:sendername

Content Class

urn:content-classes:message

Named Constant

None

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Remarks

This field corresponds to the Sender header field of RFC 822.

This field differs from the urn:schemas:httpmail:sender field in that only the display name is returned. All RFC 1522 encoded characters are decoded and returned as UNICODE characters.

Example

John Kelly

See Also

senderemail Field, sender Field, IMessage.Sender


sendmsg Field

Read-only. The mail submission URI to which outgoing mail should be submitted.

Full Name

urn:schemas:httpmail:sendmsg

Named Constant

CdoHTTPMail.cdoSendMsg

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Remarks

You can use the Microsoft Web Storage System OLE DB provider or the WebDAV protocol to send messages using Microsoft Exchange 2000 Server. Each mailbox has a corresponding URI used for this purpose. The urn:schemas:httpmail:sendmsg property returns this URI for the particular mailbox.

Example

http://server.microsoft.com/exchange/user1/##DavMailSubmissionURI##

(URL Encoded: http://server.microsoft.com/exchange/user1/%23%23DavMailSubmissionURI%23%23)

See Also

urn:schemas:httpmail:savedestination, urn:schemas:httpmail:saveinsent, The Exchange Mail Submission URI


sentitems Field

Read-only. The URL to a user's Sent Items folder.

Full Name

urn:schemas:httpmail:sentitems

Named Constant

CdoHTTPMail.cdoSentItmes

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Remarks

This field is set on a user's root mailbox folder to identify the URL to their Sent Items folder.

Example

http://server.microsoft.com/exchange/UserAlias/Sent%20Items


subject Field

The subject of the message.

Full Name

urn:schemas:httpmail:subject

Content Class

urn:content-classes:appointment

urn:content-classes:message

Named Constant

CdoHTTPMail.cdoSubject

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Remarks

This field corresponds to the Subject header field of RFC 822.

This field differs from the urn:schemas:mailheader:subject field only in that all RFC 1522 encoded characters are decoded and returned as UNICODE characters.

Example

Make $20,000 per week stuffing envelopes.


submitted Field

Set to indicate whether a message has been submitted to the Outbox.

Full Name

urn:schemas:httpmail:submitted

Content Class

urn:content-classes:message

Named Constant

CdoHTTPMail.cdoSubmitted

OLE DB Type

DBTYPE_BOOL

Variant Subtype

[Visual Basic] Boolean

[C++] VARIANT_BOOL

Example

False

© 2000-2001 Microsoft Corporation. All rights reserved.


tasks Field

Read-only. The URL to a user's Tasks folder.

Full Name

urn:schemas:httpmail:tasks

Named Constant

None

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Remarks

This field is set on a user's root mailbox folder to identify the URL to their Tasks folder.

Example

file://./backofficestorage/<domain>/MBX/<username>/Tasks


textdescription Field

The plain text content of the message.

Full Name

urn:schemas:httpmail:textdescription

Content Class

urn:content-classes:appointment

urn:content-classes:message

Named Constant

CdoHTTPMail.cdoTextDescription

Variant SubType

[Visual Basic] String

[C++] BSTR

Example

"The agenda for today's staff meeting has been changed"


thread-topic Field

The topic for conversation threading and is used when correlating the conversation threads.

Full Name

urn:schemas:httpmail:thread-topic

Content Class

urn:content-classes:message

Named Constant

CdoHTTPMail.cdoThreadTopic

Variant Subtype

[Visual Basic] String

[C++] BSTR

OLE DB Type

DBTYPE_WSTR

Remarks

This field differs from urn:schemas:mailheader:thread-topic only in that all characters encoded per RFC 1522 are decoded and returned as UNICODE characters.

Example

Parking Restrictions at work

See Also

urn:schemas:mailheader:thread-topic Field


to Field

The principle (To) message addressees.

Full Name

urn:schemas:httpmail:to

Content Class

urn:content-classes:message

Named Constant

CdoHTTPMail.cdoTo

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Remarks

This field differs from the urn:schemas:mailheader:to field only in that all RFC 1522 encoded characters are decoded and returned as UNICODE characters.

Example

"John Smith" <jsmith123@microsoft.com>, "Fred Smith" <frsmith@microsoft.com>"

See Also

urn:schemas:mailheader:to Field

IMessage.To

© 2000-2001 Microsoft Corporation. All rights reserved.


unreadcount Field

The number of unread messages in a folder.

Full Name

urn:schemas:httpmail:unreadcount

Content Class

urn:content-classes:folder

Named Constant

CdoHTTPMail.cdoUnreadCount

OLE DB Type

DBTYPE_I4

Variant Subtype

[Visual Basic] Long

[C++] long

Example

21


urn:schemas:mailheader: Namespace

The urn:schemas:mailheader: namespace defines fields that contain Internet standard message header values. Each field value (with a few exceptions) is stored as US-ASCII characters and is identical to the ASCII string found in the message stream. Non-US-ASCII characters are encoded according to the RFC 1522 specification. No conversion is performed when the property value is set or updated. An application that sets a raw message header property within this namespace must encode any non-US-ASCII characters as defined in RFC 1522. If these characters are not encoded, the header field value is corrupted.

String constants are provided in the C++ header file cdosysstr.h and type library, cdoMailHeader module, for each field name. You can use these constants when referring to the fields to avoid mistakes and extra typing.

Example

The following example demonstrates the use of the fields in the urn:schemas:mailheader: namespace. First, RFC 822 headers are added for a message. Next, body parts are added and the MIME headers are set manually.

This code is for illustrative purposes only.

[Visual Basic]
Dim iMsg as New CDO.Message
Dim Flds as ADODB.Fields
With iMsg
  .To   = """SomeOne"" <someone@microsoft.com>"
  .From = """Me"" <me@microsoft.com>"
  .Subject = "Here is a sample message"

' Now set some custom mail headers using the raw fields collection
   Set Flds = .Fields
   With Flds
    .Item("urn:schemas:mailheader:X-Mailer")  = "Microsoft CDO for Microsoft Exchange"
      ' I add a custom header here
    .Item("urn:schemas:mailheader:Myheader")= "some value"
    .Update
   End With
End With ' iMsg

   ' Create a multipart/alternative (HTML) message below

   Dim iBp as CDO.IBodyPart
   Dim iBp2 as CDO.IBodyPart

   Set iBp = iMsg   '  get IBodyPart on Message object

   Set Flds = iBp.Fields
   Flds("urn:schemas:mailheader:content-type") = "multipart/alternative"
   Flds.Update

   Set iBp2 = iBp.AddBodyPart
   Set Flds = iBp2.Fields
   Flds("urn:schemas:mailheader:content-type") = "text/plain"
   Flds("urn:schemas:mailheader:content-transfer-encoding") = "quoted-printable"
   Flds.Update

   Dim Stm as ADODB.Stream
   Set Stm = iBp2.GetDecodedContentStream
   Stm.WriteText "This is a test", stWriteLine
   Stm.Flush

   Set iBp2 = iBp.AddBodyPart
   Set Flds = iBp2.Fields
   Flds("urn:schemas:mailheader:content-type") = "text/html"
   Flds("urn:schemas:mailheader:content-transfer-encoding") = "quoted-printable"
   Flds.Update

   Set Stm = iBp2.GetDecodedContentStream
   Stm.WriteText "This is a <i>test</i>", stWriteLine
   Stm.Flush

   iMsg.Send
[C++,IDL]
#import "d:\program files\common files\system\ado\msado15.dll" no_namespace
#import "c:\program files\common files\microsoft shared\cdo\cdoex.dll" no_namespace

void main()
{
  CoInitialize(NULL);
  {

    IMessagePtr iMsg(__uuidof(Message));
    FieldsPtr   Flds;
    _StreamPtr  pStm;

    iMsg->To      = "\"SomeOne\" <someone@microsoft.com>";
    iMsg->From    = "\"Me\" <me@microsoft.com>";
    iMSg->Subject = "This is a test message";
    // Now set some custom headers for the message
    Flds = iMsg->Fields;
    Flds->Item["urn:schemas:mailheader:X-Mailer"]->Value   = "Microsoft CDO for Windows 2000";
    Flds->Item["urn:schemas:mailheader:Myheader"]->Value = "come value";
    Flds->Update();

    IBodyPartPtr iBp;
    iBp = iMsg;
    IBodyPartPtr iBp2;
    Flds = iBp->Fields;
    Flds->Item["urn:schemas:mailheader:content-type"]->Value = "multipart/alternative";
    Flds->Update();

    iBp2 = iBp->AddBodyPart(-1);
    Flds = iBp2->Fields;
    Flds->Item["urn:schemas:mailheader:content-type"]->Value = "text/plain";
    Flds->Item["urn:schemas:mailheader:content-transfer-encoding"]->Value = "quoted-printable";
    Flds->Update();

    pStm = iBp2->GetDecodedContentStream();
    pStm->WriteText("This is a test",stWriteLine);
    pStm->Flush();

    iBp2 = iBp->AddBodyPart(-1);
    Flds = iBp2->Fields;
    Flds->Item["urn:schemas:mailheader:content-type"]->Value = "text/html";
    Flds->Item["urn:schemas:mailheader:content-transfer-encoding"]->Value = "quoted-printable";
    Flds->Update();

    pStm = iBp2->GetDecodedContentStream();
    pStm->WriteText("This is a <i>test</i>",stWriteLine);
    pStm->Flush();

    iMsg->Send();
  }
  CoUninitialize();
}


approved Field

The address of the moderator that approved and posted a message.

Full Name

urn:schemas:mailheader:approved

Content Class

urn:content-classes:message

Named Constant

CdoMailHeader.cdoApproved

OLE DB Type

DBTYPE_STR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Remarks

This header is present for any message posted to a moderated newsgroup. It is added by the moderator and consists of the moderator’s e-mail address.

Example

someone@microsoft.com


bcc Field

The blind carbon copy addressees of the message.

Full Name

urn:schemas:mailheader:bcc

Content Class

urn:content-classes:message

OLE DB Type

DBTYPE_STR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Remarks

The Bcc addresses are returned as US-ASCII characters, and the addresses are separated by commas. All non-US-ASCII characters are returned encoded as defined in RFC 1522. To access the Bcc addresses as Unicode characters, use the urn:schemas:httpmail:bcc field.

Example

"SomeOne" <someone@microsoft.com>

See Also

urn:schemas:httpmail:bcc Field


cc Field

The carbon copy addressees of the message.

Full Name

urn:schemas:mailheader:cc

Content Class

urn:content-classes:message

OLE DB Type

DBTYPE_STR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Remarks

The Cc addresses are returned as US-ASCII characters, and the addresses are separated by commas. All non-US-ASCII characters are returned encoded as defined in RFC 1522. To access the Cc addresses as Unicode characters, use the urn:schemas:httpmail:cc field.

Example

“Some User, Jr” someuser@microsoft.com>, "Another User, Jr" <another@microsoft.com>

See Also

urn:schemas:httpmail:cc Field


comment Field

A comment for the message.

Full Name

urn:schemas:mailheader:comment

Content Class

urn:content-classes:message

Named Constant

CdoMailHeader.cdoComment

OLE DB Type

DBTYPE_STR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Example

This is an e-mail message about the new company dress code policy.


content-base Field

A base for relative Uniform Resource Identifiers (URIs) occurring in other header fields and in HTML documents that do not have any BASE element within the HTML markup.

Full Name

urn:schemas:mailheader:content-base

Content Class

urn:content-classes:message

Named Constant

CdoMailHeader.cdoContentBase

OLE DB Type

DBTYPE_STR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Remarks

The value must be an absolute URI.

Example

http://www.microsoft.com/exchange/


content-description Field

An optional description of a body part.

Full Name

urn:schemas:mailheader:content-description

Content Class

urn:content-classes:message

Named Constant

CdoMailHeader.cdoContentDescription

OLE DB Type

DBTYPE_STR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Example

This body part contains a message.


content-disposition Field

The intended disposition of the body part.

Full Name

urn:schemas:mailheader:content-disposition

Content Class

urn:content-classes:message

Named Constant

CdoMailHeader.cdoContentDisposition

OLE DB Type

DBTYPE_STR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Remarks

This field corresponds to the Content-Disposition MIME header field for a body part.

Example

attachment; filename=picture.gif


content-id Field

A unique identifier for the body part.

Full Name

urn:schemas:mailheader:content-id

Content Class

urn:content-classes:message

Named Constant

CdoMailHeader.cdoContentId

OLE DB Type

DBTYPE_STR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Remarks

This field corresponds to the Content-ID MIME header field and facilitates referencing one MIME body part from another.

This field has a special meaning for multipart/alternative messages. See RFC 2046 for more information.

Example

someone@microsoft.com


content-language Field

The language identifier for the body part text content.

Full Name

urn:schemas:mailheader:content-language

Content Class

urn:content-classes:message

Named Constant

CdoMailHeader.cdoContentLanguage

OLE DB Type

DBTYPE_STR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Remarks

This field is used to indicate the languages of an object that has RFC-822-like headers; for example, a MIME body part or a Web document.

Example

en, fr, de, da, el, it


content-location Field

The URI that corresponds to the content of the body part.

Full Name

urn:schemas:mailheader:content-location

Content Class

urn:content-classes:message

Named Constant

CdoMailHeader.cdoContentLocation

OLE DB Type

DBTYPE_STR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Remarks

This field can be used to show that the same information in the body part is available, in identical format, at another URI.

Example

http://www.microsoft.com/exchange/cdo.gif


content-transfer-encoding Field

The encoding mechanism used to encode the body part content.

Full Name

urn:schemas:mailheader:content-transfer-encoding

Content Class

urn:content-classes:message

Named Constant

CdoMailHeader.cdoContentTransferEncoding

OLE DB Type

DBTYPE_STR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Example

quoted-printable


content-type Field

The body part content type.

Full Name

urn:schemas:mailheader:content-type

Content Class

urn:content-classes:message

Named Constant

CdoMailHeader.cdoContentType

OLE DB Type

DBTYPE_STR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Remarks

This field describes the data contained in the body fully enough that the receiving user-agent can pick an appropriate agent or mechanism to present the data. A complete content-type header field includes the content-media-type and any number of optional parameters.

Example

text/plain; charset="iso-8859-1"


control Field

A Usenet control command.

Full Name

urn:schemas:mailheader:control

Content Class

urn:content-classes:message

Named Constant

CdoMailHeader.cdoControl

OLE DB Type

DBTYPE_STR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Remarks

Messages with a Control header are deemed control messages by NNTP services. Control messages are used for communication among Usenet host machines, and are not to be read by users.

Example

Cancel <123456@microsoft.com>

© 2000-2001 Microsoft Corporation. All rights reserved.


date Field

The date on which the message was sent.

Full Name

urn:schemas:mailheader:date

Content Class

urn:content-classes:message

OLE DB Type

DBTYPE_FILETIME

Variant Subtype

[Visual Basic] Date

[C++] DATE

Remarks

This property is identical to the urn:schemas:httpmail:date property.

Example

Tue, 6 Oct 1999 11:15:08 -0700

© 2000-2001 Microsoft Corporation. All rights reserved.


disposition Field

A Mail Delivery Notifications (MDN) status indicator for the message.

Full Name

urn:schemas:mailheader:disposition

Content Class

urn:content-classes:message

Named Constant

CdoMailHeader.cdoDisposition

OLE DB Type

DBTYPE_STR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Example

manual-action/MDN-sent-manually; displayed


disposition-notification-to Field

Where disposition notifications should be sent.

Full Name

urn:schemas:mailheader:disposition-notification-to

Content Class

urn:content-classes:message

Named Constant

CdoMailHeader.cdoDispositionNotificationTo

OLE DB Type

DBTYPE_STR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Remarks

Corresponds to the Disposition-Notification-To field on an RFC 2298 MDN request.

Example

"Person A" <persona@microsoft.com>

© 2000-2001 Microsoft Corporation. All rights reserved.


distribution Field

A comma-separated list similar to the Newsgroups header field, intended to restrict the distribution of a message.

Full Name

urn:schemas:mailheader:distribution

Content Class

urn:content-classes:message

Named Constant

CdoMailHeader.cdoDistribution

OLE DB Type

DBTYPE_STR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Example

microsoft.public.exchange.cdo,microsoft.public.exchange.setup


expires Field

The date on which the message expires.

Full Name

urn:schemas:mailheader:expires

Content Class

urn:content-classes:message

Named Constant

CdoMailHeader.cdoExpires

OLE DB Type

DBTYPE_STR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Remarks

This field corresponds to the RFC 1036 Expires: mail header field.

Example

Sat, 12 Dec 1999 00:00:00 –0800

© 2000-2001 Microsoft Corporation. All rights reserved.


expiry-date Field

The expiry date of a message in a mail header. Outlook uses this in internet mode for setting the expiration date of a message.

Full Name

urn:schemas:mailheader:expiry-date

Content Class

urn:content-classes:message

OLE DB Type

DBTYPE_STR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Example

Tue, 02 May 2000 21:42:52 -0700

© 2000-2001 Microsoft Corporation. All rights reserved.


followup-to Field

The newsgroups to which follow-up messages are to be posted.

Full Name

urn:schemas:mailheader:followup-to

Content Class

urn:content-classes:message

Named Constant

CdoMailHeader.cdoFollowupTo

OLE DB Type

DBTYPE_STR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Remarks

This field corresponds to the Followup-To: mail header field.

Multiple newsgroups can be specified using this field by placing a comma between each group.

This field can also be set using the IMessage.FollowUpTo property on an object.

Example

microsoft.public.exchange.cdo

See Also

IMessage.FollowUpTo Property

© 2000-2001 Microsoft Corporation. All rights reserved.


from Field

The addressees from whom the message was sent.

Full Name

urn:schemas:mailheader:from

Content Class

urn:content-classes:message

OLE DB Type

DBTYPE_STR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Example

“SomeOne” <someone@microsoft.com>

See Also

urn:schemas:httpmail:from Field


importance Field

Indicates the level of importance for a message as either low, normal, or high.

Full Name

urn:schemas:mailheader:importance

Content Class

urn:content-classes:message

Named Constant

CdoImportanceValues.cdoLow

CdoImportanceValues.cdoNormal

CdoImportanceValues.cdoHigh

OLE DB Type

DBTYPE_STR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Example

"high”

© 2000-2001 Microsoft Corporation. All rights reserved.


in-reply-to Field

The message identifier of the message to which this message is a reply.

Full Name

urn:schemas:mailheader:in-reply-to

Content Class

urn:content-classes:message

Named Constant

CdoMailHeader.cdoInReplyTo

OLE DB Type

DBTYPE_STR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Remarks

This corresponds to the RFC 822 InReplyTo mail header field.

Example

"12345" <12345@microsoft.com>

© 2000-2001 Microsoft Corporation. All rights reserved.


keywords Field

The keywords for the message.

Full Name

urn:schemas:mailheader:keywords

Content Class

urn:content-classes:message

OLE DB Type

DBTYPE_STR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Remarks

This corresponds to the RFC 822 Keywords mail header field.

The keywords are returned as US-ASCII characters. All non-US-ASCII characters are returned encoded as defined in RFC 1522. For decoded Unicode characters, use the IMessage.Keywords property.

Example

CDO,Messaging,Collaboration,Microsoft

See Also

IMessage.Keywords Property

© 2000-2001 Microsoft Corporation. All rights reserved.


lines Field

Contains a count of the number of lines in the body of the (newsgroup) message.

Full Name

urn:schemas:mailheader:lines

Content Class

urn:content-classes:message

Named Constant

CdoMailHeader.cdoLines

OLE DB Type

DBTYPE_STR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Example

9


message-id Field

A unique identifier for the message.

Full Name

urn:schemas:mailheader:message-id

Content Class

urn:content-classes:message

Named Constant

CdoMailHeader.cdoMessageId

OLE DB Type

DBTYPE_STR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Remarks

RFC 822 defines message-ID as a unique identifier for each version of each message, in the form local-part@domain.

Example

123456@microsoft.com

© 2000-2001 Microsoft Corporation. All rights reserved.


mime-version Field

The version of MIME used to format the message.

Full Name

urn:schemas:mailheader:mime-version

Content Class

urn:content-classes:message

Named Constant

CdoMailHeader.cdoMIMEVersion

OLE DB Type

DBTYPE_STR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Remarks

This field is defined by RFC 2045.

Example

1.0


newsgroups Field

The newsgroup addressees for the message.

Full Name

urn:schemas:mailheader:newsgroups

Content Class

urn:content-classes:message

Named Constant

CdoMailHeader.cdoNewsgroups

OLE DB Type

DBTYPE_STR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Example

microsoft.public.exchange.cdo, microsoft.public.exchange.setup


organization Field

The organization of the sender.

Full Name

urn:schemas:mailheader:organization

Content Class

urn:content-classes:message

Named Constant

CdoMailHeader.cdoOrganization

OLE DB Type

DBTYPE_STR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Remarks

This field corresponds to the Organization: header field on a message posted to a newsgroup.

Example

Microsoft Corporation

© 2000-2001 Microsoft Corporation. All rights reserved.


original-recipient Field

The e-mail address of an original recipient of the message.

Full Name

urn:schemas:mailheader:original-recipient

Content Class

urn:content-classes:message

Named Constant

CdoMailHeader.cdoOriginalRecipient

OLE DB Type

DBTYPE_STR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Remarks

Used with Mail Delivery Notifications (MDN) to provide automatic correlation for receipts on a per-recipient basis.

Example

"Sender" <sender@microsoft.com>

© 2000-2001 Microsoft Corporation. All rights reserved.


path Field

The list of NNTP hosts through which this message was relayed before arriving at the current host.

Full Name

urn:schemas:mailheader:path

Content Class

urn:content-classes:message

Named Constant

CdoMailHeader.cdoPath

OLE DB Type

DBTYPE_STR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Example

uppssnewspub03.moswest.msn.net!uppssnewspub05.moswest.msn.net


posting-version Field

Identifies the software used to post the message.

Full Name

urn:schemas:mailheader:posting-version

Content Class

urn:content-classes:message

Named Constant

CdoMailHeader.cdoPostingVersion

OLE DB Type

DBTYPE_STR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Example

Microsoft® Outlook® Express 5.0

© 2000-2001 Microsoft Corporation. All rights reserved.


priority Field

Identifies the priority of a message or appointment: normal, urgent, or nonurgent.

Full Name

urn:schemas:mailheader:priority

Content Class

urn:content-classes:message

Named Constant

CdoMailHeader.cdoPriority

OLE DB Type

DBTYPE_STR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Remarks

Use the values from the cdoPriorityValues enumeration.

Example

[Visual Basic]
' message header looks something like:
' Priority: urgent
Dim iMsg as New CDO Message
Dim Flds as ADODB.Fields
Set Flds = iMsg.Fields
Flds(CdoMailHeader.cdoPriority) = cdoPriorityUrgent
Flds.Update
© 2000-2001 Microsoft Corporation. All rights reserved.


received Field

Read-only. The SMTP host Received headers for a message.

Full Name

urn:schemas:mailheader:received

Content Class

urn:content-classes:message

Named Constant

CdoMailHeader.cdoReceived

OLE DB Type

DBTYPE_STR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Remarks

This field contains all of the Received: headers for the message, delimited by a carriage return/line feed delimiter (\r\n).

Example

Received: from xyz.com (xyz.sender.com [205.228.200.20]) by dfssl.exchange.microsoft.com with SMTP (Microsoft® Exchange Internet Mail Service Version 5.5.2232.9) id VDCMJG3C; Sat, 17 Oct 1998 23:28:29 -0700

Received: from jmith (xyz.sender.com [205.228.195.158]) by sender.com (8.9.0/8.7.3) with SMTP id BAA08159; Sun, 18 Oct 1998 01:31:28 -0500 (CDT)


references Field

The Usenet header used to correlate replies with their original messages.

Full Name

urn:schemas:mailheader:references

Content Class

urn:content-classes:message

Named Constant

CdoMailHeader.cdoReferences

OLE DB Type

DBTYPE_STR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Example

<12345@exchange.microsoft.com>

© 2000-2001 Microsoft Corporation. All rights reserved.


relay-version Field

The version of the program responsible for transmitting this article over the immediate link. In other words, the program that is relaying the article from the other site.

Full Name

urn:schemas:mailheader:relay-version

Content Class

urn:content-classes:message

Named Constant

CdoMailHeader.cdoRelayVersion

OLE DB Type

DBTYPE_STR

Variant Subtype

[Visual Basic] String

[C++] BSTR

© 2000-2001 Microsoft Corporation. All rights reserved.


reply-by Field

Indicates when there should be a reply to a message.

Full Name

urn:schemas:mailheader:reply-by

Content Class

urn:content-classes:message

OLE DB Type

DBTYPE_STR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Example

"Tuesday”

© 2000-2001 Microsoft Corporation. All rights reserved.


reply-to Field

The address to which replies should be sent.

Full Name

urn:schemas:mailheader:reply-to

Content Class

urn:content-classes:message

OLE DB Type

DBTYPE_STR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Remarks

This corresponds to the RFC 822 Reply-To mail header field.

The Bcc addresses are returned as US-ASCII characters, and the addresses are separated by commas. All non-US-ASCII characters are returned encoded as defined in RFC 1522. To access the Bcc addresses as Unicode characters, use the urn:schemas:httpmail:reply-to field.

Example

"12345" <12345@microsoft.com>

See Also

urn:schemas:httpmail:reply-to Field


return-path Field

The address of the message originator.

Full Name

urn:schemas:mailheader:return-path

Content Class

urn:content-classes:message

Named Constant

CdoMailHeader.cdoReturnPath

OLE DB Type

DBTYPE_STR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Remarks

This field corresponds to the Return-Path: message header field.

Example

"John Kelly" <johnkelly@microsoft.com>

© 2000-2001 Microsoft Corporation. All rights reserved.


return-receipt-to Field

The address to which return receipts should be sent.

Full Name

urn:schemas:mailheader:return-receipt-to

Content Class

urn:content-classes:message

Named Constant

CdoMailHeader.cdoReturnReceiptTo

OLE DB Type

DBTYPE_STR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Remarks

This is a widely used, but nonstandard, Return-Receipt-To: message header.

Example

"John Kelly" <johnkelly@microsoft.com>

© 2000-2001 Microsoft Corporation. All rights reserved.


sender Field

The sender of the message.

Full Name

urn:schemas:mailheader:sender

Content Class

urn:content-classes:message

OLE DB Type

DBTYPE_STR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Remarks

The sender field corresponds to the Sender: mail header field of RFC 822. It is used to designate who actually sent a message when the From: header has multiple addresses, or when the sender is not the single addressee on the From: header.

The sender field is returned as US-ASCII characters. All non-US-ASCII characters are returned encoded as defined in RFC 1522. To access the field as Unicode characters, use the urn:schemas:httpmail:sender field.

Example

"Person A" <personA@microsoft.com>

See Also

urn:schemas:httpmail:sender Field


sensitivity Field

The sensitivity of the message or appointment. Valid values are None, Personal, Private, and Company Confidential. This field corresponds to the Sensitivity: mail header.

Full Name

urn:schemas:mailheader:sensitivity

Content Class

urn:content-classes:message

Named Constant

CdoMailHeader.cdoSensitivity

OLE DB Type

DBTYPE_STR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Remarks

Use the values from the cdoSensitivityValues enumeration.

Example

cdoPrivate


subject Field

The subject of the message.

Full Name

urn:schemas:mailheader:subject

Content Class

urn:content-classes:appointment

urn:content-classes:message

OLE DB Type

DBTYPE_STR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Remarks

The subject is returned as US-ASCII characters. All non-US-ASCII characters are returned encoded as defined in RFC 1522. To access the field as Unicode characters, use the urn:schemas:httpmail:subject field or the IMessage.Subject property.

Example

Status mail brought to you by Microsoft CDO for Windows® 2000


summary Field

A summary of the message.

Full Name

urn:schemas:mailheader:summary

Content Class

urn:content-classes:message

Named Constant

CdoMailHeader.cdoSummary

OLE DB Type

DBTYPE_STR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Example

This is a memo about company policy.


thread-index Field

Identifies a particular conversation thread; computed from message references.

Full Name

urn:schemas:mailheader:thread-index

Content Class

urn:content-classes:message

Named Constant

CdoMailHeader.cdoThreadIndex

OLE DB Type

DBTYPE_STR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Example

Ab7TEZtW04eKS19qTMukQad1gGNu3A

© 2000-2001 Microsoft Corporation. All rights reserved.


thread-topic Field

The topic of a discussion thread.

Full Name

urn:schemas:mailheader:thread-topic

Content Class

urn:content-classes:message

OLE DB Type

DBTYPE_STR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Remarks

This field corresponds to the Thread-Topic: mail header field.

The thread topic is returned as US-ASCII characters. All non-US-ASCII characters are returned encoded as defined in RFC 1522. To access the field as Unicode characters, use the urn:schemas:httpmail:thread-topic field.

Example

What is the parking situation like downtown?

See Also

urn:schemas:httpmail:thread-topic Field


to Field

The principal (To) message addressees.

Full Name

urn:schemas:mailheader:to

Content Class

urn:content-classes:message

OLE DB Type

DBTYPE_STR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Remarks

The To addresses are returned as US-ASCII characters, and the addresses are separated by commas. All non-US-ASCII characters are returned encoded as defined in RFC 1522. To access the addresses as Unicode characters, use the urn:schemas:httpmail:to field or the IMessage.To property.

Example

"SomeUser" someuser@microsoft.com>, "Another" <another@microsoft.com>

See Also

urn:schemas:httpmail:to Field

IMessage.To Property

© 2000-2001 Microsoft Corporation. All rights reserved.


x-mailer Field

The name of the software used to send the message.

Full Name

urn:schemas:mailheader:x-mailer

Content Class

urn:content-classes:message

Named Constant

CdoMailHeader.cdoXMailer

OLE DB Type

DBTYPE_STR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Remarks

This field corresponds to the x-mailer message header.


x-message-completed Field

Microsoft Outlook header for message flag completion.

Full Name

urn:schemas:mailheader:x-message-completed

Content Class

urn:content-classes:message

Named Constant

none

OLE DB Type

DBTYPE_STR

Variant Subtype

[Visual Basic] String

[C++] BSTR

© 2000-2001 Microsoft Corporation. All rights reserved.


x-message-flag Field

Platform SDK: Exchange 2000 Server

x-message Flag Field

Message flag used by Microsoft Outlook.

Full Name

urn:schemas:mailheader:x-message-flag

Content Class

urn:content-classes:message

OLE DB Type

DBTYPE_STR

Variant Subtype

[Visual Basic] String

[C++] BSTR

© 2000-2001 Microsoft Corporation. All rights reserved.


x-unsent Field

Indicates whether or not a message has been completed during authoring.

Full Name

urn:schemas:mailheader:x-unsent

Content Class

urn:content-classes:message

Named Constant

CdoMailHeader.cdoXUnsent

OLE DB Type

DBTYPE_STR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Remarks

Used by Outlook Express to designate that a message is currently being authored. The value of this field can be either "TRUE" or "FALSE."

Example

"TRUE"

© 2000-2001 Microsoft Corporation. All rights reserved.


xref Field

Contains the name of the host (with domains omitted) and a white–space-separated list of colon-separated pairs of newsgroup names and message numbers.

Full Name

urn:schemas:mailheader:xref

Content Class

urn:content-classes:message

Named Constant

CdoMailHeader.cdoXref

OLE DB Type

DBTYPE_STR

Variant Subtype

[Visual Basic] String

[C++] BSTR

© 2000-2001 Microsoft Corporation. All rights reserved.


urn:schemas-microsoft-com:datatypes Namespace

The urn:schemas-microsoft-com:datatypes namespace defines a field used when defining properties for the Microsoft® Web Storage System schema.


type Field

Indicates the property type in a property schema definition.

Full Name

urn:schemas-microsoft-com:datatypes#type

Content Class

urn:content-classes:propertydef

Constant Name

None

OLE DB Type

DBTYPE_WSTR

Variant SubType

[Visual Basic] String

[C++] BSTR

Remarks

Set this property to one of the following values when defining a property through a urn:content-classes:propertydef class item in the store:

XML Type | Corresponding OLE DB Type | MAPI Property Type
bin.base64 | DBTYPE_BYTES1 |
bin.hex | Not Supported |
boolean | DBTYPE_BOOL |
char | DBTYPE_WSTR |
date | DBTYPE_DATE |
dateTime | DBTYPE_DATE |
dateTime.tz |  | PT_APPTIME, PT_SYSTIME
fixed.14.4 |  | PT_CURRENCY
float | DBTYPE_R8 |
i2 | DBTYPE_I2 |
i4 | DBTYPE_I4 |
i8 | DBTYPE_I8 |
int |  | PT_LONG
number | Not Supported |
r4 | DBTYPE_R4 |
r8 | DBTYPE_R8 |
string | DBTYPE_WSTR |
time | Not Supported |
time.tz | Not Supported |
ui1 | DBTYPE_UI1 |
ui2 | DBTYPE_UI2 |
ui4 | Not Supported |
ui8 | Not Supported |
uri |  | PT_CLSID
uuid | DBTYPE_GUID |

1. Binary data is encoded using the base64 encoding algorithm for HTTP request and retrieval.

These types are used to distinguish the type when the property is transmitted to WebDAV clients.

Example

string


urn:schemas-microsoft-com:exch-data: Namespace

Definitions for Exchange-specific data types used for Web Storage System properties.


baseschema

An array of URLs identifying other folders within the same store that contain schema definition items.

Full Name

urn:schemas-microsoft-com:exch-data:baseschema

Content Class

urn:content-classes:folder

OLE DB Type

DBTYPE_ARRAY | DBTYPE_VARIANT

Variant SubType (Automation)

Array of Variants (Strings) [Visual Basic]

VT_ARRAY | VT_VARIANT (VT_BSTR) [C++]

Remarks

Use the baseschema property in conjunction with the urn:schemas-microsoft-com:exch-data:schema-collection-ref property to define a folder's schema scope. Set this property on any folder containing schema definition items to identify subsequent folders that should be searched for schema items. Applications always check the current folder before proceeding to the folders identified by the baseschema property.

The order in which the URLs are listed in this property is significant: When searching for schema definition items, applications perform a breadth-first search for definition items within the folder's schema scope starting in the folder identified by urn:schemas-microsoft-com:exch-data:schema-collection-ref. Folders subsequently identified by the baseschema property of this schema collection folder are then searched in the order that they appear in the property. During the search, the first encountered definition item is always used, and other subsequent definition items are ignored. Each baseschema folder can then in turn define its own set of baseschema folders. These folders are searched in the order that they appear in the property.

Example

"file://./backofficestorage/domain/store/MyAppFolder1a/schema/"

"file://./backofficestorage/domain/store/MyAppFolder1b/schema/"

See Also

urn:schemas-microsoft-com:exch-data:schema-collection-ref

Web Storage System Schema

© 2000-2001 Microsoft Corporation. All rights reserved.


closedexpectedcontentclasses

Reserved for future use.

Full Name

urn:schemas-microsoft-com:exch-data:closedexpectedcontentclasses

Content Class

urn:content-classes:contentclassdef

OLE DB Type

DBTYPE_BOOL

Variant SubType (Automation)

Boolean [Visual Basic]

VT_BOOL [C++]


ase

Platform SDK: Exchange 2000 Server

codebase

Application developers can use this property to define the URL where clients can download Microsoft® ActiveX® components to render or handle items of this content class. The value of this property is not used or interpreted in any way by the Microsoft Web Storage System.

Full Name

urn:schemas-microsoft-com:exch-data:codebase

Content Class

urn:content-classes:contentclassdef

OLE DB Type

DBTYPE_WSTR

Variant SubType (Automation)

String [Visual Basic]

BSTR [C++]

Remarks

Application developers can use this property for a content class definition to list the URL to a COM component cabinet installation file. This property is very similar in intended functionality to the codebase attribute in an HTML <OBJECT> tag.

Use of this property is application-specific and does not affect the operation of a Web Storage System.

Example

http://myserver/comcmpnts/mycomponent.cab


comclassid

Application developers can use this property to identify the COM class they intend to handle items of this content class. The value of this property is not used or interpreted in any way by the Web Storage System.

Full Name

urn:schemas-microsoft-com:exch-data:comclassid

Content Class

urn:content-classes:contentclassdef

OLE DB Type

DBTYPE_WSTR

Variant SubType (Automation)

String [Visual Basic]

BSTR [C++]

Remarks

This property, along with the urn:schemas-microsoft-com:exch-data:comprogid, identifies a COM class that can be used to handle or process items of this content class. This mechanism is similar in intent to the MAPI Forms registry, where the PR_MESSAGE_CLASS has an associated form CLSID that can render and process the item for the user.

Use of this property is application-specific and does not affect the operation of a Web Storage System.


comprogid

Application developers can use this property to identify the COM class that they intend to handle items of this content class. The value of this property is not used or interpreted in any way by the Web Storage System.

Full Name

urn:schemas-microsoft-com:exch-data:comprogid

Content Class

urn:content-classes:contentclassdef

OLE DB Type

DBTYPE_WSTR

Variant SubType (Automation)

String [Visual Basic]

BSTR [C++]

Remarks

This property, along with the urn:schemas-microsoft-com:exch-data:comclassid, identifies to a client the COM class that can be used to handle or process items of this content class. This mechanism is similar in intent to the MAPI Forms registry, where the PR_MESSAGE_CLASS has an associated form CLSID that can render and process the item for the user.

The use of this property is application-specific and does not affect the operation of a Web Storage System.


default

Used when creating a schema property definition to indicate the default value of such a property.

Full Name

urn:schemas-microsoft-com:exch-data:default

Content Class

urn:content-classes:propertyoverride

urn:content-classes:propertydef

OLE DB Type

DBTYPE_WSTR

Variant SubType (Automation)

String [Visual Basic]

BSTR [C++]

Remarks

Use this property when creating a schema property definition item to indicate what the property's default value is.


dictionary

Reserved for future use.

Full Name

urn:schemas-microsoft-com:exch-data:dictionary

Content Class

urn:content-classes:propertyoverride

urn:content-classes:propertydef


expected-content-class

An array of names indicating the expected content classes of items within a folder.

Full Name

urn:schemas-microsoft-com:exch-data:expected-content-class

Content Class

urn:content-classes:contentclassdef

urn:content-classes:folder

OLE DB Type

DBTYPE_ARRAY | DBTYPE_VARIANT

Variant SubType (Automation)

Array of Variants (Strings) [Visual Basic]

VT_ARRAY | VT_VARIANT (VT_BSTR) [C++]

Remarks

The expected-content-class property is an array (list) of content class names that are designated as expected for items in the folder. This property does not itself define these content classes and does not define in what folder or folders the associated content class and property definition items are kept. Applications search for these definitions within the folder's schema scope. Additionally, the expected-content-class property does not impose a restriction on what the value of an item's content class can be; it simply designates the list of names as expected for items within the folder.

One example use of the expected-content-class property is controlling which properties are returned for items when you execute a SELECT * command on a folder: only the combination of properties defined by all of the expected content classes are returned for each item in the resulting OLE DB Rowset or ADO Recordset.

The expected-content-class, schema-collection-ref and baseschema properties are used together to define a folder's schema. Folders can contain separate content class and property definitions specific to a particular application. For more information about folder schemas, see Web Storage System Schema.

See Also

urn:schemas-microsoft-com:exch-data:schema-collection-ref

urn:schemas-microsoft-com:exch-data:baseschema

Web Storage System Schema

© 2000-2001 Microsoft Corporation. All rights reserved.


iscontentindexed

Reserved for future use.

Full Name

urn:schemas-microsoft-com:exch-data:iscontentindexed

Content Class

urn:content-classes:propertydef

OLE DB Type

DBTYPE_BOOL

Variant SubType (Automation)

Boolean [Visual Basic]

VARIANT_BOOL [C++]

Remarks

This property is reserved for future use.


isindexed

Used when defining a schema property item to indicate whether the property is indexed.

Full Name

urn:schemas-microsoft-com:exch-data:isindexed

Content Class

urn:content-classes:propertydef

OLE DB Type

DBTYPE_BOOL

Variant SubType (Automation)

Boolean [Visual Basic]

VT_BOOL [C++]


ismultivalued

Used when defining a property to indicate whether the property is multivalued. If so, the property can contain multiple values of the type defined with the urn:schemas-microsoft-com:datatypes#type property on the property definition item.

Full Name

urn:schemas-microsoft-com:exch-data:ismultivalued

Content Class

urn:content-classes:propertydef

OLE DB Type

DBTYPE_BOOL

Variant SubType (Automation)

Boolean [Visual Basic]

VT_BOOL [C++]

Remarks

This property is for informational purposes and does not restrict the value of a property in any way.

See Also

urn:schemas-microsoft-com:datatypes#type


isreadonly

Used when defining a property to indicate whether the property is read-only.

Full Name

urn:schemas-microsoft-com:exch-data:isreadonly

Content Class

urn:content-classes:propertydef

OLE DB Type

DBTYPE_BOOL

Variant SubType (Automation)

Boolean [Visual Basic]

VT_BOOL [C++]

Remarks

Only the properties provided by the Web Storage System are marked as read-only. These properties are never set by applications; they are provided by the store.


isrequired

Used when defining a property to indicate whether the property is required by a particular application.

Full Name

urn:schemas-microsoft-com:exch-data:isrequired

Content Class

urn:content-classes:propertyoverride

urn:content-classes:propertydef

OLE DB Type

DBTYPE_BOOL

Variant SubType (Automation)

Boolean [Visual Basic]

VT_BOOL [C++]

Remarks

If you specify a property as being required by your application, you must enforce that requirement in your application. The store does not force applications to set this property when creating or saving item properties.


isvisible

Used when defining a property to indicate whether the property should be visible.

Full Name

urn:schemas-microsoft-com:exch-data:isvisible

Content Class

urn:content-classes:propertydef

OLE DB Type

DBTYPE_BOOL

Variant SubType (Automation)

Boolean [Visual Basic]

VT_BOOL [C++]

Remarks

If you specify a property as being "visible" by your application, you must enforce this requirement from within your application.


propertydef

The name of the property overridden by a propertyoverride.

Full Name

urn:schemas-microsoft-com:exch-data:propertydef

Content Class

urn:content-classes:propertyoverride

OLE DB Type

DBTYPE_WSTR

Variant SubType (Automation)

String [Visual Basic]

BSTR [C++]


schema-collection-ref

A Uniform Resource Locator (URL) identifying the first folder in which to look for schema definition items.

Full Name

urn:schemas-microsoft-com:exch-data:schema-collection-ref

Content Class

urn:content:classes:item

urn:content:classes:object

OLE DB Type

DBTYPE_WSTR

Variant SubType (Automation)

String [Visual Basic]

BSTR [C++]

Remarks

Use this property to define the first folder within its schema scope. The value is the URL of the first folder in which to search for schema content class and property definition items. If no value is set, the folder's schema scope defaults to the non_ipm_subtree/Schema folder in that public or private store.

See Also

Web Storage System Schema

urn:schemas-microsoft-com:exch-data:baseschema


synchronize

Used when defining a property to indicate whether the item's stream should be updated when this property is set on the row.

Full Name

urn:schemas-microsoft-com:exch-data:synchronize

Content Class

urn:content-classes:propertyoverride

urn:content-classes:propertydef

OLE DB Type

DBTYPE_BOOL

Variant SubType (Automation)

Boolean [Visual Basic]

VT_BOOL [C++]

Remarks

The Web Storage System does not automatically synchronize an item's properties and stream. Application programmers can use this property to indicate that synchronization is required and then properly synchronize the properties and stream manually.

This property has no effect on the operation of the Web Storage System.


version

An optional version value for schema definition items. This property has no effect on the schema definitions or their operation in the store.

Full Name

urn:schemas-microsoft-com:exch-data:version

Content Class

urn:content-classes:propertyoverride

urn:content-classes:contentclassdef

urn:content-classes:propertydef

OLE DB Type

DBTYPE_I4

Variant SubType (Automation)

Long [Visual Basic]

VT_I4 [C++]

Remarks

When defining schemas for Web Storage System applications, use this property to specify the version of the definition item.

This property has no impact on the operation of the store.


urn:schemas.microsoft.com:fulltextqueryinfo Namespace

This namespace defines properties used for full text searching.


all Field

Reserved for future use.

Full Name

urn:schemas.microsoft.com:fulltextqueryinfo:all

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Example

<n/a>

© 2000-2001 Microsoft Corporation. All rights reserved.


catalogname Field

This is the name of the search catalog the result came from.

Full Name

urn:schemas.microsoft.com:fulltextqueryinfo:catalogname

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Example

My Catalog

© 2000-2001 Microsoft Corporation. All rights reserved.


crawlmodifiedtime Field

Reserved for future use.

Full Name

urn:schemas.microsoft.com:fulltextqueryinfo:crawlmodifiedtime

OLE DB Type

FILETIME

Variant Subtype

[Visual Basic] DateTime

[C++] Date

Example

#3/29/1999 1:30:00 PM#

© 2000-2001 Microsoft Corporation. All rights reserved.


docsignature Field

MD5 digest of a document.

Full Name

urn:schemas.microsoft.com:fulltextqueryinfo:docsignature

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Example

any text


filename Field

The long filename.

Full Name

urn:schemas.microsoft.com:fulltextqueryinfo:filename

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Example

filename.txt


filepath Field

The path to the file.

Full Name

urn:schemas.microsoft.com:fulltextqueryinfo:filepath

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Example

c:\windows


hitcount Field

This returns the number of search results that matched a query.

Full Name

urn:schemas.microsoft.com:fulltextqueryinfo:hitcount

OLE DB Type

DBTYPE_I4

Variant Subtype

[Visual Basic] Long

[C++] long

Example

23


htmlcomment Field

Comments in HTML documents.

Full Name

urn:schemas.microsoft.com:fulltextqueryinfo:htmlcomment

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Example

any text


nlprank Field

Reserved for future use.

Full Name

urn:schemas.microsoft.com:fulltextqueryinfo:nlprank

OLE DB Type

DBTYPE_I4

Variant Subtype

[Visual Basic] Long

[C++] long

© 2000-2001 Microsoft Corporation. All rights reserved.


rank Field

Read-only. This is the relevance rank of search results.

Full Name

urn:schemas.microsoft.com:fulltextqueryinfo:rank

OLE DB Type

DBTYPE_I4

Variant Subtype

[Visual Basic] Long

[C++] long

Example

23


rankvector Field

Ranks of individual components of a vector query.

Full Name

urn:schemas.microsoft.com:fulltextqueryinfo:rankvector

OLE DB Type

VECTOR LONG

Variant Subtype

[Visual Basic] Long

[C++] long

Example

{1, 3, 46}


shortfilename Field

The short (8.3) filename.

Full Name

urn:schemas.microsoft.com:fulltextqueryinfo:shortfilename

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Example

filename.txt


sitename Field

The Web site name.

Full Name

urn:schemas.microsoft.com:fulltextqueryinfo:sitename

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Example

mysite


unfiltered Field

True if the collection is unfiltered.

Full Name

urn:schemas.microsoft.com:fulltextqueryinfo:unfiltered

OLE DB Type

DBTYPE_BOOL

Variant Subtype

[Visual Basic] Boolean

[C++] VARIANT_BOOL

Example

True

© 2000-2001 Microsoft Corporation. All rights reserved.


usn Field

Reserved for future use.

Full Name

urn:schemas.microsoft.com:fulltextqueryinfo:usn

OLE DB Type

DBTYPE_I8

Variant Subtype

[Visual Basic] Long

[C++] long

Example

23


workid Field

Reserved for future use.

Full Name

urn:schemas.microsoft.com:fulltextqueryinfo:workid

OLE DB Type

DBTYPE_I4

Variant Subtype

[Visual Basic] Long

[C++] long

Example

23


urn:schemas-microsoft-com:office:forms Namespace

This namespace defines properties used to register HTML forms in Web Storage System.


binding

Specifies the binding type.

Full Name

urn:schemas-microsoft-com:office:forms#binding

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Remarks

This property is case-insensitive. Possible values are server, client, and Web-client.

Example

IE

© 2000-2001 Microsoft Corporation. All rights reserved.


browser

Specifies the type of browser.

Full Name

urn:schemas-microsoft-com:office:forms#browser

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Remarks

This property is case-insensitive. An asterisk (*) indicates a wildcard to designate all browsers.

Example

IE

© 2000-2001 Microsoft Corporation. All rights reserved.


cmd

A case-insensitive string that denotes the action or behavior being performed on an object.

Full Name

urn:schemas-microsoft-com:office:forms#cmd

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Remarks

The cmd can either be a unique string defined in a form registration or a predefined command.

This is the first parameter after the command (?Cmd= of the URL returned from IIS roughly corresponding to the ISAPI QUERY_STRING.). The QUERY_STRING is delimited by ampersands (&) that represent modifiers of the action.

Examples: Get, NewArt

Predefined Commands
Command | Description
Edit | Edit an item
Forward |
Get | Get defines how data is requested from the server.
New | New creates a new item.
Open | Open an item for reading
Post | Post defines how data is submitted to the server.
Reply, Reply All, Forward, Delete | Message Operations
Save | Save an item
Send | Send a message
Navbar | Display navigation bar
Contents | Display the right pane
Options | Display options settings


contentclass

The content class for which the form is registered. This property is case insensitive. The contentclass is associated with a set of schemas and a set of forms.

Full Name

urn:schemas-microsoft-com:office:forms#contentclass

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Example

urn:content-classes:message.


contentstate

This property is used to match forms against the value of the http://schemas.microsoft.com/exchange/contentstate property. The state can be set on any item.

Full Name

urn:schemas-microsoft-com:office:forms#contentstate

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

© 2000-2001 Microsoft Corporation. All rights reserved.


executeparameters

Parameters to pass to the form-rendering engine specified by the "executeurl" property. The value of this property must be URL escaped.

Full Name

urn:schemas-microsoft-com:office:forms#executeparameters

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Example

param1=a, m2=url%20escaped


executeurl

The URL of the engine used to render a form. This can be an ASP form, and ISAPI filter.

Full Name

urn:schemas-microsoft-com:office:forms#executeurl

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

© 2000-2001 Microsoft Corporation. All rights reserved.


formurl

The URL of the form or template. The form URL is what is being registered; this can be a relative or absolute URL.

Full Name

urn:schemas-microsoft-com:office:forms#formurl

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

© 2000-2001 Microsoft Corporation. All rights reserved.


language

The language of the form, provided as part of the HTTP request headers.

Full Name

urn:schemas-microsoft-com:office:forms#language

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Example

EN

Remarks

This property corresponds to a case-insensitive ISO language-country value in the Accept-Language HTTP header.


majorver

The major version of the browser.

Full Name

urn:schemas-microsoft-com:office:forms#majorver

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Example

5


messagestate

State of the item. Case insensitive values include normal, submitted, read, unread, importance.

Full Name

urn:schemas-microsoft-com:office:forms#messagestate

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

© 2000-2001 Microsoft Corporation. All rights reserved.


minorver

The minor version of the browser.

Full Name

urn:schemas-microsoft-com:office:forms#minorver

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Remarks

The friendly name of the browser's minor version.

The minorver must be an integer value. For example:

minorver = 0


platform

Indicates the platform of the browser. This property is case insensitive and has the same format as in browscap.ini.

Full Name

urn:schemas-microsoft-com:office:forms#platform

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

© 2000-2001 Microsoft Corporation. All rights reserved.


request

Specifies whether the form uses a GET or a POST request. This property is case-insensitive.

Full Name

urn:schemas-microsoft-com:office:forms#request

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Remarks

This is a friendly name request.

There are only two possible values, GET and POST.


version

The browser version.

Full Name

urn:schemas-microsoft-com:office:forms#version

OLE DB Type

DBTYPE_WSTR

Variant Subtype

[Visual Basic] String

[C++] BSTR

Remarks

The version is a string value. For example:

version = 5.0b

or

version = 5.00.2919.6307

Note Version takes priority over majorver and minor ver.


urn:schemas-microsoft-com:office:office Namespace

This namespaces defines properties for use with Microsoft® Office applications.


Author Field

The name of the document author.

Full Name

urn:schemas-microsoft-com:office:office#Author

Content Class

urn:content-classes:document

OLE DB Type

DBTYPE_WSTR

© 2000-2001 Microsoft Corporation. All rights reserved.


Bytes Field

The size of the document in bytes.

Full Name

urn:schemas-microsoft-com:office:office#Bytes

Content Class

urn:content-classes:document

OLE DB Type

DBTYPE_I4

© 2000-2001 Microsoft Corporation. All rights reserved.


Category Field

A comma separated list of categories.

Full Name

urn:schemas-microsoft-com:office:office#Category

Content Class

urn:content-classes:document

OLE DB Type

DBTYPE_WSTR

Remarks

This field is automatically synchronized with the http://schemas.microsoft.com/exchange/categories field.


Characters Field

The number of characters in the document.

Full Name

urn:schemas-microsoft-com:office:office#Characters

Content Class

urn:content-classes:document

OLE DB Type

DBTYPE_I4

© 2000-2001 Microsoft Corporation. All rights reserved.


Checked_x0020_by Field

A status property used by Microsoft® Office applications.

Full Name

urn:schemas-microsoft-com:office:office#Checked_x0020_by

Content Class

urn:content-classes:document

OLE DB Type

DBTYPE_WSTR

Remarks

This field is located on the Custom tab in the Properties dialog box within Office applications.


Client Field

A status property used by Microsoft® Office applications.

Full Name

urn:schemas-microsoft-com:office:office#Client

Content Class

urn:content-classes:document

OLE DB Type

DBTYPE_WSTR

Remarks

This field is located on the Custom tab in the Properties dialog box within Office applications.


Comments Field

Comments for the document.

Full Name

urn:schemas-microsoft-com:office:office#Comments

Content Class

urn:content-classes:document

OLE DB Type

DBTYPE_WSTR

Remarks

This field is located on the Custom tab in the Properties dialog box within Office applications.


Company Field

The author's company.

Full Name

urn:schemas-microsoft-com:office:office#Company

Content Class

urn:content-classes:document

OLE DB Type

DBTYPE_WSTR

Remarks

This field is located on the Custom tab in the Properties dialog box within Office applications.


Created Field

The date and time that an office document was created.

Full Name

urn:schemas-microsoft-com:office:office#Created

Content Class

urn:content-classes:document

OLE DB Type

DBTYPE_FILETIME

© 2000-2001 Microsoft Corporation. All rights reserved.


Date_x0020_completed Field

A status property used by Microsoft® Office applications.

Full Name

urn:schemas-microsoft-com:office:office#Date_x0020_completed

Content Class

urn:content-classes:document

OLE DB Type

DBTYPE_WSTR

Remarks

This field is located on the Custom tab in the Properties dialog box within Office applications.


Department Field

The author's department.

Full Name

urn:schemas-microsoft-com:office:office#Department

Content Class

urn:content-classes:document

OLE DB Type

DBTYPE_WSTR

Remarks

This field is located on the Custom tab in the Properties dialog box within Office applications.


Destination Field

A status property used by Microsoft® Office applications.

Full Name

urn:schemas-microsoft-com:office:office#Destination

Content Class

urn:content-classes:document

OLE DB Type

DBTYPE_WSTR

Remarks

This field is located on the Custom tab in the Properties dialog box within Office applications.


Disposition Field

A status property used by Microsoft® Office applications.

Full Name

urn:schemas-microsoft-com:office:office#Disposition

Content Class

urn:content-classes:document

OLE DB Type

DBTYPE_WSTR

Remarks

This field is located on the Custom tab in the Properties dialog box within Office applications.


Division Field

A status property used by Microsoft® Office applications.

Full Name

urn:schemas-microsoft-com:office:office#Division

Content Class

urn:content-classes:document

OLE DB Type

DBTYPE_WSTR

Remarks

This field is located on the Custom tab in the Properties dialog box within Office applications.


Document_x0020_number Field

A status property used by Microsoft® Office applications.

Full Name

urn:schemas-microsoft-com:office:office#Document_x0020_number

Content Class

urn:content-classes:document

OLE DB Type

DBTYPE_WSTR

Remarks

This field is located on the Custom tab in the Properties dialog box within Office applications.


Editor Field

A status property used by Microsoft® Office applications.

Full Name

urn:schemas-microsoft-com:office:office#Editor

Content Class

urn:content-classes:document

OLE DB Type

DBTYPE_WSTR

Remarks

This field is located on the Custom tab in the Properties dialog box within Office applications.


Forward_x0020_to Field

A status property used by Microsoft® Office applications.

Full Name

urn:schemas-microsoft-com:office:office#Forward_x0020_to

Content Class

urn:content-classes:document

OLE DB Type

DBTYPE_WSTR

Remarks

This field is located on the Custom tab in the Properties dialog box within Office applications.


Group Field

A status property used by Microsoft® Office applications.

Full Name

urn:schemas-microsoft-com:office:office#Group

Content Class

urn:content-classes:document

OLE DB Type

DBTYPE_WSTR

Remarks

This field is located on the Custom tab in the Properties dialog box within Office applications.


HeadingPairs Field

A status property used by Microsoft® Office applications.

Full Name

urn:schemas-microsoft-com:office:office#HeadingPairs

Content Class

urn:content-classes:document

OLE DB Type

DBTYPE_WSTR

© 2000-2001 Microsoft Corporation. All rights reserved.


HiddenSlides Field

A status property used by Microsoft® Office applications.

Full Name

urn:schemas-microsoft-com:office:office#HiddenSlides

Content Class

urn:content-classes:document

OLE DB Type

DBTYPE_I4

Remarks

The number of hidden slides in the document. http://officeweb/specs/webclient/officedocprops.htm.


Keywords Field

A list of keywords for this document.

Full Name

urn:schemas-microsoft-com:office:office#Keywords

Content Class

urn:content:classes:item

OLE DB Type

DBTYPE_VECTOR WSTR

Remarks

This is similar to the urn:schemas:mailheader:keywords field except that this field returns the keywords with all RFC 1522 encoded characters decoded into the appropriate character set.


Language Field

The language in which the document was written.

Full Name

urn:schemas-microsoft-com:office:office#Language

Content Class

urn:content-classes:document

OLE DB Type

DBTYPE_WSTR

Remarks

This field is located on the Custom tab in the Properties dialog box within Office applications.


LastAuthor Field

A status property used by Microsoft® Office applications.

Full Name

urn:schemas-microsoft-com:office:office#LastAuthor

Content Class

urn:content-classes:document

OLE DB Type

DBTYPE_WSTR

Remarks

Person who last saved the document.


LastPrinted Field

A status property used by Microsoft® Office applications.

Full Name

urn:schemas-microsoft-com:office:office#LastPrinted

Content Class

urn:content-classes:document

OLE DB Type

DBTYPE_FILETIME

Remarks

Date and time when last printed.


LastSaved Field

A status property used by Microsoft® Office applications.

Full Name

urn:schemas-microsoft-com:office:office#LastSaved

Content Class

urn:content-classes:document

OLE DB Type

DBTYPE_FILETIME

Remarks

This field is located on the Custom tab in the Properties dialog box within Office applications.


Lines Field

A status property used by Microsoft® Office applications.

Full Name

urn:schemas-microsoft-com:office:office#Lines

Content Class

urn:content-classes:document

OLE DB Type

DBTYPE_I4

Remarks

The number of lines in the document.


LinksUpToDate Field

A status property used by Microsoft® Office applications.

Full Name

urn:schemas-microsoft-com:office:office#LinksUpToDate

Content Class

urn:content-classes:document

OLE DB Type

DBTYPE_BOOL

© 2000-2001 Microsoft Corporation. All rights reserved.


MailStop Field

A status property used by Microsoft® Office applications.

Full Name

urn:schemas-microsoft-com:office:office#MailStop

Content Class

urn:content-classes:document

OLE DB Type

DBTYPE_WSTR

Remarks

This field is located on the Custom tab in the Properties dialog box within Office applications.


Manager Field

A status property used by Microsoft® Office applications.

Full Name

urn:schemas-microsoft-com:office:office#Manager

Content Class

urn:content-classes:document

OLE DB Type

DBTYPE_WSTR

Remarks

Manager of the author of the page. This is different than urn:schemas:contacts:manager, because this one is an attribute of the document and not a value in the document. They can exist hypothetically at the same time.


Matter Field

A status property used by Microsoft® Office applications.

Full Name

urn:schemas-microsoft-com:office:office#Matter

Content Class

urn:content-classes:document

OLE DB Type

DBTYPE_WSTR

Remarks

This field is located on the Custom tab in the Properties dialog box within Office applications.


MultimediaClips Field

A status property used by Microsoft® Office applications.

Full Name

urn:schemas-microsoft-com:office:office#MultimediaClips

Content Class

urn:content-classes:document

OLE DB Type

DBTYPE_I4

Remarks

The number of multimedia clips in the document.


NameOfApplication Field

A status property used by Microsoft® Office applications.

Full Name

urn:schemas-microsoft-com:office:office#NameOfApplication

Content Class

urn:content-classes:document

OLE DB Type

DBTYPE_WSTR

Remarks

Name of the application.


Notes Field

A status property used by Microsoft® Office applications.

Full Name

urn:schemas-microsoft-com:office:office#Notes

Content Class

urn:content-classes:document

OLE DB Type

DBTYPE_I4

Remarks

The number of notes in the document. This is very different from urn:schemas:httmail:notes, which points to the notes folder.


Office Field

A status property used by Microsoft® Office applications.

Full Name

urn:schemas-microsoft-com:office:office#Office

Content Class

urn:content-classes:document

OLE DB Type

DBTYPE_WSTR

Remarks

This field is located on the Custom tab in the Properties dialog box within Office applications.


Owner Field

A status property used by Microsoft® Office applications.

Full Name

urn:schemas-microsoft-com:office:office#Owner

Content Class

urn:content-classes:document

OLE DB Type

DBTYPE_WSTR

Remarks

This field is located on the Custom tab in the Properties dialog box within Office applications.


Pages Field

A status property used by Microsoft® Office applications.

Full Name

urn:schemas-microsoft-com:office:office#Pages

Content Class

urn:content-classes:document

OLE DB Type

DBTYPE_I4

Remarks

Number of pages in an office document.


Paragraphs Field

A status property used by Microsoft® Office applications.

Full Name

urn:schemas-microsoft-com:office:office#Paragraphs

Content Class

urn:content-classes:document

OLE DB Type

DBTYPE_I4

Remarks

The number of paragraphs in the document.http://officeweb/specs/webclient/officedocprops.htm.


PartTitles Field

A status property used by Microsoft® Office applications.

Full Name

urn:schemas-microsoft-com:office:office#PartTitles

Content Class

urn:content-classes:document

OLE DB Type

DBTYPE_VECTOR WSTR

© 2000-2001 Microsoft Corporation. All rights reserved.


PresentationFormat Field

A status property used by Microsoft® Office applications.

Full Name

urn:schemas-microsoft-com:office:office#PresentationFormat

Content Class

urn:content-classes:document

OLE DB Type

DBTYPE_WSTR

Remarks

The presentation form for the document.


Project Field

A status property used by Microsoft® Office applications.

Full Name

urn:schemas-microsoft-com:office:office#Project

Content Class

urn:content-classes:document

OLE DB Type

DBTYPE_WSTR

Remarks

This field is located on the Custom tab in the Properties dialog box within Office applications.


Publisher Field

A status property used by Microsoft® Office applications.

Full Name

urn:schemas-microsoft-com:office:office#Publisher

Content Class

urn:content-classes:document

OLE DB Type

DBTYPE_WSTR

Remarks

This field is located on the Custom tab in the Properties dialog box within Office applications.


Purpose Field

A status property used by Microsoft® Office applications.

Full Name

urn:schemas-microsoft-com:office:office#Purpose

Content Class

urn:content-classes:document

OLE DB Type

DBTYPE_WSTR

Remarks

This is an office document property.


Received Field

A status property used by Microsoft® Office applications.

Full Name

urn:schemas-microsoft-com:office:office#Received

Content Class

urn:content-classes:document

OLE DB Type

DBTYPE_WSTR

Remarks

This is an office document property.


Recorded Field

A status property used by Microsoft® Office applications.

Full Name

urn:schemas-microsoft-com:office:office#Recorded

Content Class

urn:content-classes:document

OLE DB Type

DBTYPE_WSTR

Remarks

This is an office document property.


Recorded_x0020_date Field

A status property used by Microsoft® Office applications.

Full Name

urn:schemas-microsoft-com:office:office#Recorded_x0020_date

Content Class

urn:content-classes:document

OLE DB Type

DBTYPE_WSTR

Remarks

This is an office document property.


Reference Field

A status property used by Microsoft® Office applications.

Full Name

urn:schemas-microsoft-com:office:office#Reference

Content Class

urn:content-classes:document

OLE DB Type

DBTYPE_WSTR

Remarks

This is an office document property.


Revision Field

A status property used by Microsoft® Office applications.

Full Name

urn:schemas-microsoft-com:office:office#Revision

Content Class

urn:content-classes:document

OLE DB Type

DBTYPE_WSTR

Remarks

Revision number of the document.


ScaleCrop Field

A status property used by Microsoft® Office applications.

Full Name

urn:schemas-microsoft-com:office:office#ScaleCrop

Content Class

urn:content-classes:document

OLE DB Type

DBTYPE_BOOL

Remarks

For images.


Security Field

A status property used by Microsoft® Office applications.

Full Name

urn:schemas-microsoft-com:office:office#Security

Content Class

urn:content-classes:document

OLE DB Type

DBTYPE_I4

Remarks

This is an office document property.


Slides Field

A status property used by Microsoft® Office applications.

Full Name

urn:schemas-microsoft-com:office:office#Slides

Content Class

urn:content-classes:document

OLE DB Type

DBTYPE_I4

Remarks

The number of slides in the document.


Source Field

A status property used by Microsoft® Office applications.

Full Name

urn:schemas-microsoft-com:office:office#Source

Content Class

urn:content-classes:document

OLE DB Type

DBTYPE_WSTR

Remarks

This is an office document property.


Status Field

A status property used by Microsoft® Office applications.

Full Name

urn:schemas-microsoft-com:office:office#Status

Content Class

urn:content-classes:document

OLE DB Type

DBTYPE_WSTR

Remarks

This is an office document property.


Subject Field

A status property used by Microsoft® Office applications.

Full Name

urn:schemas-microsoft-com:office:office#Subject

Content Class

urn:content-classes:document

OLE DB Type

DBTYPE_WSTR

Remarks

Subject of the document. This is different from the mailheaders subject property, which is usually the display name.

The mail headers one is used for the display of mail messages. For a word doc, you want this to display the filename, not the Word subject.


Telephone_x0020_number Field

A status property used by Microsoft® Office applications.

Full Name

urn:schemas-microsoft-com:office:office#Telephone_x0020_number

Content Class

urn:content-classes:document

OLE DB Type

DBTYPE_WSTR

Remarks

This is an Office document property.


Template Field

A status property used by Microsoft® Office applications.

Full Name

urn:schemas-microsoft-com:office:office#Template

Content Class

urn:content-classes:document

OLE DB Type

DBTYPE_WSTR

Remarks

Pathname to the template for the file.


ThumbNail Field

A status property used by Microsoft® Office applications.

Full Name

urn:schemas-microsoft-com:office:office#ThumbNail

Content Class

urn:content-classes:document

OLE DB Type

DBTYPE_BYTES

Remarks

This is the thumbnail image of the document or part of the document.


Title Field

A status property used by Microsoft® Office applications.

Full Name

urn:schemas-microsoft-com:office:office#Title

Content Class

urn:content-classes:document

OLE DB Type

DBTYPE_WSTR

© 2000-2001 Microsoft Corporation. All rights reserved.


TotalTime Field

A status property used by Microsoft® Office applications.

Full Name

urn:schemas-microsoft-com:office:office#TotalTime

Content Class

urn:content-classes:document

OLE DB Type

DBTYPE_FILETIME

Remarks

Total editing time for the document.


Typist Field

A status property used by Microsoft® Office applications.

Full Name

urn:schemas-microsoft-com:office:office#Typist

Content Class

urn:content-classes:document

OLE DB Type

DBTYPE_WSTR

Remarks

This is an Office document property.


Version Field

A status property used by Microsoft® Office applications.

Full Name

urn:schemas-microsoft-com:office:office#Version

Content Class

urn:content-classes:document

OLE DB Type

DBTYPE_I4

© 2000-2001 Microsoft Corporation. All rights reserved.


Words Field

A status property used by Microsoft® Office applications.

Full Name

urn:schemas-microsoft-com:office:office#Words

Content Class

urn:content-classes:document

OLE DB Type

DBTYPE_I4

Remarks

The number of words in the document.


urn:schemas-microsoft-com:xml-data Namespace

The urn:schemas-microsoft-com:xml-data namespace defines properties (fields) used when defining Web Storage System content classes and properties.

You specify the names of properties that are associated with a particular content class by listing these names in the content class definition item's urn:schemas-microsoft-com:xml-data#element field. Each named property must have a corresponding definition item within the applicable folder's schema scope.

You specify the names of content classes a content class extends by listing these names in the content class definition item's urn:schemas-microsoft-com:xml-data#extends property. Each named content class must have a corresponding definition item within the applicable folder's schema scope.

You specify the name of a property or content class definition in a definition item's urn:schemas-microsoft-com:xml-data#name property. This name should be the fully qualified name of the content class or property. This name is referenced in other definition items.


element Field

Used when defining a content class to indicate the names of property definition items associated with the class.

Full Name

urn:schemas-microsoft-com:xml-data#element

Content Class

urn:content-classes:contentclassdef

OLE DB Type

DBTYPE_VECTOR | DBTYPE_VARIANT (VT_BSTR)

Variant SubType

Array of Variants (Strings) [Visual Basic]

VT_ARRAY | VT_VARIANT (VT_BSTR) [C++]

Remarks

This multi-valued string property lists the names of property definition objects and property definition override objects defined as associated with items of this content class. Property definition names for properties defined by content classes that this content class extends are inherited and need not be listed in this property.

For example, if you wish to create a custom content class called urn:content-classes:myclass that includes all the property definitions of the urn:content-classes:item content class, you can set your class definition item's urn:schemas-microsoft-com:xml-data#extends property to "urn:content-classes:item". Then, you need only add those property definition names to the urn:schemas-microsoft-com:xml-data#element property that are not already defined by the urn:content-classes:item content class. The property definition names defined by the urn:content-classes:item are inherited by the class definition when it is designated as extending the urn:content-classes:item content class.


extends Field

Used when defining a content class to indicate the list of content classes this class extends.

Full Name

urn:schemas-microsoft-com:xml-data#extends

OLE DB Type

DBTYPE_VECTOR | DBTYPE_VARIANT (VT_BSTR)

Variant SubType

Array of Variants (Strings) [Visual Basic]

VT_ARRAY | VT_VARIANT (VT_BSTR) [C++]

Remarks

This multi-valued string property lists the names of content classes a class extends. The class definition thereby inherits the properties defined by those content classes. Additional properties defined for a content class are listed in the urn:schemas-microsoft-com:xml-data#element property. A content class can extend any number of content classes, including none.

A content class definition can simply extend another class and not list additional property definition names. In this case, the content class is equivalent to the extended content class, differing only in name. In other words, the list of property definitions is the same for both classes.

For example, you may wish to define a set of custom content classes for each specific type of document in an application you create. When you define these content classes, you can have each class "inherit" the properties defined by the base urn:content-classes:document content class. In this way, you avoid having to list all of the numerous properties already defined by this base content class in the definition item's urn:schemas-microsoft-com:xml-data#element property. Depending upon your intended use for these custom content classes, you may add your own additional custom property definition references to these classes as well.


name Field

Used when defining a content class or property to indicate its name.

Full Name

urn:schemas-microsoft-com:xml-data#name

OLE DB Type

DBTYPE_WSTR

Variant Subtype

String [Visual Basic]

VT_BSTR [C++]

Remarks

This name is used to refer to the content class or the property definition. For example, content class definition items refer to property definitions using these names within their urn:schemas-microsoft-com:exch-data#element multi-valued string property. The value of the DAV:contentclass property present for all items in a Web Storage System refer to the name of a content class.

To avoid conflicts with other applications when defining custom content classes and property definitions, a namespace convention should be used. For example, you could name your content classes using the namespace urn:my-company-tld:content-classes: and name custom properties similarly. In this way, the possibility of name collision is reduced.


Web Storage System SQL

This section is a reference of the SQL grammar you can use to perform searches on the Web Storage System.

See Also

Web Storage System Search

Searching The Web Storage System

© 2000-2001 Microsoft Corporation. All rights reserved.


Token Formats

The Web Storage System SQL uses the concept of tokens values for search conditions in the WHERE clause. Tokens must be delimited by single quotes. A token can contain only alphabetic characters unless they are surrounded by double quotes. In the following WHERE clause, "this" and "that" are tokens:

WHERE CONTAINS (' "this" AND "that" ')

This clause does not work:

WHERE CONTAINS ('10 dollars')

To fix the clause, surround the token with double quotes within the single quotes:

WHERE CONTAINS ('"10 dollars"')


CAST Function

Use CAST to attribute a data type to a property in the returned recordset. Casting only supports XML data types.

Casting is optional and is primarily used for working with custom properties whose data type is not known by the Web Storage System. The Web Storage System recognizes all data types for the schema as installed by Microsoft® Exchange 2000 Server. Custom properties not cast are evaluated as string values. Casting Boolean properties is unnecessary.

Syntax

CAST(value AS datatype)
value
Either a property or a literal string.
datatype
An XML data type. XML data types are case sensitive.

Remarks

By using base-64 encoding, you can encode binary custom property values in a format that can be sent in XML. All Microsoft Exchange 2000 binary properties are base-64 encoded by default. The following clause is an example where ‘a98k231KJg823kj’ is a base-64 encoded string.

WHERE CAST("custom:mybinaryprop" AS "bin.base64") > "a98k231KJg823kj"

If you want to encode using bin.hex, casting must be repeated on the comparison value as shown in these examples:

WHERE CAST("custom:mybinaryprop" AS "bin.hex") = CAST("08AF183B82" as "bin.hex"

WHERE CAST("custom:myprop" AS "string") = CAST("08AF183B82" as "bin.hex")

Examples

WHERE CAST("custom:mydateprop" AS "dateTime") > "1998-02-01T10:00"

WHERE "custom:count" > CAST("0" AS "int")

WHERE "custom:creationdate" = CAST("1999-10-22T22:12:40.296Z" as "dateTime.tz")

WHERE "custom:price" > CAST("34.88" AS "fixed.14.4")

You can cast UUID properties with or without the braces:

WHERE CAST("myguid" as "uuid") = "F04DA480-65B9-11d1-A29F-00AA00C14882"

WHERE CAST("myguid” as "uuid") = "{F04DA480-65B9-11d1-A29F-00AA00C14882}"


CONTAINS Predicate

Use CONTAINS as part of a WHERE clause to search for a word or phrase as specified. Only whole words are matched.

Syntax

CONTAINS( [" propertyNAME " | * , ] ' searchspec ' )
propertyNAME
Optional. If not specified, only the message or document body is searched. Use this parameter to search a property marked for full-text indexing in addition to searching the body. Use an asterisk (*) to include all properties marked for full-text indexing.

The property must be a quoted string, such as "urn:schemas:mailheader:to". An asterisk for this parameter is not surrounded by quotes.

searchspec
This parameter is the string to search for. See Token Formats for usage of single and double quotes. This parameter is case sensitive. You can FORMSOF in this parameter, and the following operators:
Operator Operator Word Operator Symbol
and AND &
or OR |

Note The NOT operator is only supported if it follows an AND operator.

Remarks

CONTAINS can only function if full-text indexing is applied to the store being searched. Common words, such as “and,” “is”, “but”, and “the”, also known as noise words, are bypassed in a search

Only items with the exact sequence are matched, for example Seasons Greetings.

Example

Word and Character Matching

See Also

FREETEXT Predicate

© 2000-2001 Microsoft Corporation. All rights reserved.


CREATE INDEX Function

The CREATE INDEX function indexes all properties that are defined in the parent folder’s expected content classes.

Syntax

CREATE INDEX * ON "folderURL" (*)
*
Creates all indexes. This asterisk is required.
folderURL
Specify the URL of the folder to be indexed. This parameter is the only variable in the syntax.
(*)
Creates indexes on all properties. This asterisk in parenthesis is required.

Remarks

A property must meet the following criteria to be indexed:

  • The property must have a property definition that specifies urn:schemas-microsoft-com:exch-data:isindexed as TRUE.
  • The property must be defined in at least one of the folder’s expected content classes.

This function has a shallow depth and does not operate on subfolders.

You cannot pass a property name with this function to create an individual index, and you cannot name indexes. DROP INDEX is not supported, so to delete indexes you must delete the folder, first saving its items to another folder.

Note You cannot create indexes in the installable file system M: drive.

See Also

Property Indexing

© 2000-2001 Microsoft Corporation. All rights reserved.


FORMSOF Predicate

Use FORMSOF as part of a WHERE clause to find word variations. FORMSOF is typically used within a CONTAINS or FREETEXT predicate.

Syntax

FORMSOF( type, "string" [,"string"] )
type
The type for the Web Storage System is always INFLECTIONAL.
string
This parameter contains one or more words for the search engine to find variations of those words. Each word must be delimited with double quotes and separated by commas.

Remarks

Common words, such as “and,” “is”, “but”, and “the”, also known as noise words, are bypassed in a search

When FORMSOF is within a CONTAINS or FREETEXT predicate, the FORMSOF predicate is itself a token and must be delimited by single quotes as shown in the following example:

WHERE CONTAINS('FORMSOF(INFLECTIONAL,"photograph", "announce")')

This clause would find any item containing photography, photographs, photographer, announcer, announcing and items with other forms of these words.

Example

Word and Character Matching

© 2000-2001 Microsoft Corporation. All rights reserved.


FREETEXT Predicate

Use FREETEXT as part of a WHERE clause to loosely match any item having a variation of a word or group of words.

Syntax

FREETEXT( [" propertyNAME ", ] ' searchspec ' )
propertyNAME
Optional. If not specified, only the message or document body is searched. Use this parameter to search a property marked for full-text indexing in addition to searching the body. Use an asterisk (*) to include all properties marked for full-text indexing.

The property must be a quoted string, such as "urn:schemas:mailheader:to". An asterisk for this parameter is not surrounded by quotes.

searchspec
This parameter is the string to search for. See Token Formats for usage of single and double quotes. This parameter is case sensitive. You can use FORMSOF in this parameter, and the following operators:
Operator Operator Word Operator Symbol
and AND &
or OR |

Note The NOT operator is only supported if it follows an AND operator.

Remarks

FREETEXT can only function if full-text indexing is applied to the store being searched.

Common words, such as “and,” “is”, “but”, and “the”, also known as noise words, are bypassed in a search

A group of words can match several items, such as garden rose will match any item containing garden, gardening, gardener, gardens, rose, and roses but won’t match gardenia or rosebud.

Example

Word and Character Matching

See Also

CONTAINS Predicate

© 2000-2001 Microsoft Corporation. All rights reserved.


FROM Predicate

Platform SDK: Exchange 2000 Server

FROM Clause

See the SELECT statement.


GROUP BY Predicate

The GROUP BY predicate organizes the returned recordset according to one or more of the properties specified in the SELECT statement.

Syntax

GROUP BY "properyName" , " [,"propertyNAME"]  " [,"propertyName"]
propertyName
Properties selected in your SQL query that you want to group.

Remarks

By including the property DAV:visiblecount in the SELECT statement, it tallies the occurrences of matching items as specified by GROUP BY.

Example

Getting Item Counts with GROUP BY

© 2000-2001 Microsoft Corporation. All rights reserved.


LIKE Predicate

Use the LIKE predicate as part of a general WHERE clause condition to perform character matches. LIKE does a character-by-character comparison of the specified property value and the supplied characters.

Syntax

propertyName LIKE value
propertyName
The Uniform Resource Name (URN) of the property value in which to check for value. The property URN must be a quoted string. For example, "urn:schemas:mailheader:to".
value
The value to check for within the property. The value must be a quoted string, unless the string is comprised strictly of alphanumeric characters [0-9a-zA-Z] with no spaces. You can use standard regular-expression characters within the value string. For example, "%hat%" would match any section of text within the property value that included the literal characters "hat".

Remarks

LIKE does not work on XML-formatted properties such as DAV:resourcetype.

Example

WHERE "urn:schemas:mailheader:to" LIKE "someone"

WHERE "urn:schemas:contacts:cn" LIKE "%west%"

Word and Character Matching

© 2000-2001 Microsoft Corporation. All rights reserved.


ORDER BY Clause

The ORDER BY clause sorts the returned recordset in ascending or descending order according to one or more properties specified.

ORDER BY <sortcolumn>, <sortcolumn>, … , <sortcolumn>

<sortcolumn> ::= <column> [ ASC | DESC ]

Syntax

ORDER BY "properyName", [,"propertyName"] [,"propertyName"] [ASC|DESC]
propertyName
Properties selected in your SQL query that you want to group.
asc, desc
To sort in ascending order, A-C, specify “asc.” To sort in descending order, Z-A, specify “desc.” Sorting can also be done numerically.

Remarks

You cannot use ORDER BY on properties in the Web Storage System that are calculated. For a list of these properties, Non-searchable properties.

Example

Simple Query

© 2000-2001 Microsoft Corporation. All rights reserved.


RANK BY Clause

Ranking can be used to sort results based on how frequently and where the queried strings appear in the indexed documents

Syntax

RANK BY CLAUSE(Mechanism,weight)
CLAUSE
Eiher WEIGHT or COERSION
Mechanism
Action, such as WEIGHT or MULTIPLY
weight
The significance of the rank.

Example

This example contains a SQL search string that uses clause weighting to assign certain search terms a fraction of the weight that other search terms have. The example searches all properties on the items for the term "Star" and the term "Planet." If the search engine finds only "Star" in an item, it should rank that item at one-quarter the value of an item containing "Planet."

The urn:schemas.microsoft.com:fulltextqueryinfo:rank property holds the relevant rank of search results.

strSQL = "Select ""urn:schemas:httpmail:subject"", " & """urn:schemas.microsoft.com:fulltextqueryinfo:rank"" FROM " & scope('shallow traversal of "http://myserver/public/test/""' WHERE " & "CONTAINS(*.'""Star""') RANK BY WEIGHT(0.25) OR " & "CONTAINS(*,'""Planet""') RANK BY WEIGHT(1.0)"


Range Header

This option is exclusively for clients issuing a SEARCH using the WebDAV protocol. You can specify ranges using the syntax demonstrated in the following example specifications.

Specification | Recordset result
Range: rows=20-39 | Rows 30-39
Range: rows=0-5, 10-15, 20-25, 30-35 | Discontinuous rows as specified
Range: rows=-50 | Last 50 rows
Range: rows=228- | All rows from the 228th to the end of the result set
Range: rows=0-4,-5 | The first and last five rows
Range: rows=-0 | Could be used by clients doing replication

The range specification is the HTTP request header, seen here after content length:

SEARCH /public/folder1/ HTTP/1.1

Content-Type: text/xml

Content-Length: XXX

Range: rows=20-39

Use the XMLHTTP COM Class to include the range header, as in the following example where ‘Rec’ is an XMLHTTPRequest object:

Req.setRequestHeader "Range", "rows=10-20,40-50"

See Also

Searching Folders (WebDAV)


SELECT Statement

Use the SELECT statement to select items, as records returned in a recordset, from the Web Storage System.

Syntax

SELECT list FROM SCOPE('scope1'[,'scope2','scopeN'])[ WHERE condition [ORDER BY list [DESC|ASC]] [GROUP BY list] ]
list
The list of item properties to return for each record. A SELECT * returns all properties defined in the expected content classes of the folder.

Note It is recommended to avoid using SELECT * because of processing demands on the server that could impact performance of other processes, as well as retrieving an unnecessarily large amount of data.

Note The following properties are invalid in a search because their values are only calculated when they are asked for, but not when they are searched on:

  • DAV:lockdiscovery
  • DAV:resourcetype
  • DAV:searchrequest
scope
Optional. Scopes can be shallow or deep traversals of the folder and its subordinate hierarchy. The default scope is a shallow traversal, allowing the FROM clause to be specified with just the folder’s URL. The URL must be delimited by double quotes.

FROM "file://.backofficestorage/domain/MBX/user/inbox/"

Scope is made up of two parts:

  1. SHALLOW | DEEP TRAVERSAL OF
  2. URL

Shallow traversal searches only the folder specified by the URL. Deep traversal searches that folder and recursively descends and searches all subfolders.

Note You can perform a deep traversal in all stores except the public folder installed for MAPI clients.

The URL specifies the location of the target folder in which to search. The ending slash is optional but recommended. The URL must be placed in double-quotes.

The default scope, if the SCOPE keyword is omitted, is a shallow traversal. If you specify the SCOPE keyword but do not specify the type of traversal, the default is a deep traversal.

Example

SCOPE('shallow traversal of "file://.backofficestorage/domain/MBX/user/inbox/"')
condition
The condition that must be met for the item properties specified in list to be returned.

Example

SELECT
   "urn:schemas:httpmail:to",
   "DAV:contentclass"
FROM
   "file://.backofficestorage/domain/MSX/user/inbox/"
WHERE
   "urn:schemas:httpmail:subject" LIKE "%Web Storage%"
AND
   "DAV:contentclass" = "urn:content-classes:message"
ORDER BY
   "urn:schemas:httpmail:date"
DESC

See Also

The SELECT Statement (Concepts)

Search Scope

© 2000-2001 Microsoft Corporation. All rights reserved.


WHERE Clause

Use the WHERE keyword to create a conditional clause that must be met for records to be returned. Conditions are chained together using the AND and OR keywords. Parentheses can be used to group conditions into a single logical condition.

Syntax

WHERE condition
condition
A single or set of logical conditions that, when evaluated, result in a TRUE or FALSE result. Conditions are chained using the AND and OR keywords. The following predicates can be used in a WHERE clause:
  • CAST
  • CONTAINS
  • FORMSOF
  • FREETEXT
  • GROUP BY
  • LIKE
  • ORDER BY
  • RANK BY

See Also

SELECT Statement

© 2000-2001 Microsoft Corporation. All rights reserved.


Unsupported SQL

The following SQL grammar, functions, and functionality are not supported:

  • AVG
  • CONVERT (use CAST)
  • COUNT
  • CREATE VIEW
  • DATASOURCE
  • DELETE
  • DROP INDEX
  • INSERT
  • JOINS
  • MAX
  • MIN
  • Revision ID header (ignored)
  • Scope aliases
  • SELECT DISTINCT
  • SET
  • Scope revision numbers
  • SHAPE
  • SUM
  • UNKNOWN
  • UPDATE
  • Wildcard expressions (use CONTAINS, FREETEXT, and LIKE)

This list is not comprehensive and is subject to change.


Non-Searchable Properties

The following properties cannot be searched because their values are only calculated when used and are not persisted in the Web Storage System.

  • DAV:getetag
  • DAV:href
  • DAV:lockdiscovery
  • DAV:parentname
  • DAV:resourcetype
  • DAV:searchrequest
  • http://schemas.microsoft.com/exchange/content-href
  • http://schemas.microsoft.com/exchange/ntsecuritydescriptor
  • http://schemas.microsoft.com/exchange/oof-state
  • http://schemas.microsoft.com/exchange/publicfolderemailaddress
  • http://schemas.microsoft.com/repl/repl-uid
  • http://schemas.microsoft.com/repl/resourcetag
  • urn:schemas:contacts:proxyaddresses
  • urn:schemas:httpmail:htmldescription
  • urn:schemas:httpmail:subject
  • urn:schemas:mailheader:subject
  • urn:schemas-microsoft-com:exch-data:baseschema
  • urn:schemas-microsoft-com:exch-data:schema-collection-ref

All properties that contain URL values, such as DAV:href, are calculated and UTF-8 encoded.

This list is not comprehensive and is subject to change.


Exchange OLE DB Provider

You can access resources in the Web Storage System through the Exchange OLE DB (ExOLEDB) provider. By using ActiveX Data Objects (ADO) in conjunction with the ExOLEDB provider, you can run Structured Query Language (SQL) queries and create, modify, or delete resources. This section lists cotypes supported by the ExOLEDB provider and describes extensions you can use to traverse various resources in the store.

This section contains the following topics:

Supported OLE DB CoTypes

Provider Extensions

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Supported OLE DB CoTypes

The Exchange OLE DB provider provides implementations of the following OLE DB 2.5 CoTypes:

ExOLEDB Provider Binder

Enumerator

DataSource

Session

Command

Row

RowSet

Stream

ErrorObject

© 2000-2001 Microsoft Corporation. All rights reserved.


ExOLEDB Provider Binder

The following table lists the OLE DB 2.5 interfaces implemented by the Exchange OLE DB Provider Binder COM class.

Interface | Supported
IBindResource | yes
ICreateRow | yes
IDBBinderProperties | yes
IDBProperties | yes
ISupportErrorInfo | yes

For additional information about using the Exchange OLE DB provider binder, see ICreateRow and Multiple Databases in the Session object.

For information on the OLE DB 2.5 root binder, see File URL Namespace


Enumerator

The following table lists the OLE DB 2.5 interfaces implemented by the Exchange OLE DB Enumerator COM class.

Interface | Supported
IParseDisplayName | yes
ISourcesRowset | yes
IDBInitialize | no
IDBProperties | no
ISupportErrorInfo | no


DataSource

The following table lists the OLE DB 2.5 interfaces implemented by the Exchange OLE DB DataSource COM class.

Interface | Supported
IDBCreateSession | yes
IDBInitialize | yes
IDBProperties | yes
IPersist | yes
IConnectionPointContainer | no
IDBAsynchStatus | no
IDBDataSourceAdmin | no
IDBInfo | no
IPersistFile | no
ISupportErrorInfo | yes


Session

The following table lists the OLE DB 2.5 interfaces implemented by the Exchange OLE DB Session COM class.

Interface | Supported
IGetDataSource | yes
IOpenRowset | yes
ISessionProperties | yes
IAlterIndex | no
IAlterTable | no
IBindResource | yes
ICreateRow | yes
IDBCreateCommand | yes
IDBSchemaRowset | yes
IIndexDefinition | no
ISupportErrorInfo | yes
ITableDefinition | no
ITransaction | yes
ITransactionJoin | no
ITransactionLocal | yes
ITransactionObject | no

Two-phase commit and distributed transactions are not supported.

For additional information, see ICreateRow and Multiple Databases and ITransaction.


ICreateRow and Multiple Databases

Each public top-level header and private mailbox is a separate database. When a Session object is created, it is always bound to only one database. Thus, it is impossible to use a single ICreateRow interface to create objects from different stores, such as an Exchange private and a public store: the ICreateRow interface is bound to a Session object which is bound to a single MDB database and logon. For each unique MDB that you connect to, you must create a Session object. This action also applies to the ICreateRow::CreateRow method and is the principal reason for the OLE DB 2.5 root binder. If the client is unsure of a URL's namespace or database origins, then the client can use a new instance of the root binder. This creates a new session and avoids any cross-database failures.


ITransaction

The Exchange OLE DB provider provides an implementation of the ITransactionLocal interface with the following restrictions:

  • Nested transactions are not supported.
  • The ITransactionJoin interface, used to perform two-phase commit transactions, is not supported.
  • Full transaction isolation is not supported. The provider prevents dirty reads (in other words, supported by grouped operations), yet allows non-repeatable reads or phantoms. Specifically, the provider allows read committed (i.e., cursor stability). This means that the provider will only support a value of ISOLATION_LEVEL_READCOMMITTED for the isoLevel argument of ITransactionLocal::StartTransaction. All other values specified for the isoLevel parameter will cause ITransactionLocal::StartTransaction to fail with an error reporting that this isolation level is not a valid option.


Command

The following table lists the OLE DB 2.5 interfaces implemented by the Exchange OLE DB Command COM class.

Interface | Supported
IAccessor | yes
IColumnsInfo | yes
ICommand | yes
ICommandProperties | yes
ICommandText | yes
IConvertType | yes
IColumnsRowset | no
ICommandPersist | no
ICommandPrepare | yes
ICommandWithParameters | no
ISupportErrorInfo | no

    Structured Query Language SQL joins are not supported. All other SQL constructs are supported, for example, WHERE clause, relational operators, and projections.

    ICommand

    The CONTAINS clause in an ICommand::Execute method cannot have more than 1024 characters.


Row

The following table lists the interfaces exposed for the Row CoType.

Interface | Supported
IColumnsInfo | yes
IConvertType | yes
IGetSession | yes
IRow | yes
IColumnsInfo2 | yes
IConnectionPointContainer | no
ICreateRow | yes
IDBAsynchStatus | no
IDBCreateCommand | no
IDBInitialize | no
IRowChange | yes
IRowSchemaChange | yes
IScopedOperations | yes
ISupportErrorInfo | yes


RowSet

The following table lists the interfaces exposed for the RowSet CoType.

Interface | Supported
IAccessor | yes
IColumnsInfo | yes
IConvertType | yes
IRowset | yes
IRowsetInfo | yes
IChapteredRowset | no
IColumnsInfo2 | no
IColumnsRowset | no
IConnectionPointContainer | no
IDBAsynchStatus | no
IGetRow | yes
IRowsetChange | yes
IRowsetChapterMember | no
IRowsetCurrentIndex | no
IRowsetFind | no
IRowsetIdentity | yes
IRowsetIndex | no
IRowsetLocate | yes
IRowsetRefresh | no
IRowsetScroll | no
IRowsetUpdate | no
IRowsetView | no
ISupportErrorInfo | no


Stream

The following table lists the interfaces exposed for the Stream CoType.

Interface | Supported
ISequentialStream | yes
IConnectionPointContainer | no
IDBAsynchStatus | no
IDBInitialize | no
IGetSourceRow | yes
ISupportErrorInfo | no
IStream | yes


ErrorObject

The IErrorRecords interface is supported for the ErrorObject CoType.


Provider Extensions

The Exchange OLE DB provider provides extensions specific to traversing folders and documents. Extensions are also provided for supporting the Office Web Server. These include extensions for handling Complex documents (including embedded documents) via the standard OLE DB rowset, the smallest type of document (the simple document) via CoType TRow, and hierarchy support via scoped operations. See OLE DB 2.5 for specifications on these extensions of the Office Web Server.


File URL Namespace

ExOLEDB registers with the OLE DB RootBinder to support both a public and private namespace in local Exchange private and public stores. Both namespaces are prefixed by "file://./backofficestorage". This is static—it cannot be changed by system administration or any other means. The public namespace is:

"file://./backofficestorage/DomainName/TopLevelFolder"

This is for all public folder databases, including the default MAPI public folder database. DomainName specifies the fully qualified domain name for the organization. TopLevelFolder specifies the top folder in a folder tree for a particular MDB. For example:

"file://./backofficestorage/microsoft.com/documents"

Folder trees outside of the default MAPI public folder are not visible to Outlook2000 and prior MAPI clients.

The private namespace is:

"file://./backofficestorage/DomainName/MBX/UserName"

This namespace is for all private databases. The UserName string is the part of the address string that comes before the "@" of the user's proxy address. For example:

"file://./backofficestorage/microsoft.com/MBX/user1"

Note that there is a URL per domain—not a URL per private database. Note that by having the URL per domain, the user can change their private MDB without changing the URL to the mailbox. The DomainName is the part of the user's proxy address that follows the @. By including this domain name in the private form, exchange is able to distinguish the URL for mailto:user1@microsoft.com and mailto:someone@microsoft.com.

Directory Listings

The store will notify the ExOLEDB provider when a new database is created. Also, a directory listing at the "file://./backofficestorage" level will return the list of organizations. A directory listing at the "file://./backofficestorage/DomainName" will return the list of top level folders for the specified domain or organization, including the static "MBX" string, which represents private mailboxes. A directory listing at the "file://./backofficestorage/DomainName/MBX" will return an empty list—in order to preserve mailbox privacy. However, a directory listing of a specific user, such as "file://./backofficestorage/DomainName/MBX/UserName", will give a list of the top-level folders within the IPM sub-tree (e.g., Inbox, Outbox, Deleted Items, etc.). You can change to any of these directories and continue to navigate down the folder hierarchy.

NON-IPM Sub-trees

Access to a user's NON-IPM sub-tree is via the URL "file://./backofficestorage/DomainName/MBX/UserName/NON_IPM_SUBTREE". The NON-IPM sub-tree is not visible in a directory listing of a user mailbox. The only way to access the NON-IPM sub-tree is to explicitly change the directory to the NON-IPM folder. Once bound to the NON-IPM folder, one can get a directory listing of the folders under the NON-IPM folder for a particular user.

Access to the top level of a public NON-IPM sub-tree is similar via the URL "file://./backofficestorage/DomainName/TopLevelFolderName/NON_IPM_SUBTREE". The behavior is the same as described for private databases.

Here are some additional examples for further clarification:

  • Browse To file://./backofficestorage/DomainName/

Result: List of top-level folders plus an MBX folder.

  • Browse To file://./backofficestorage/DomainName/TopLevelFolder1

Result: List of folders under TopLevelFolder1.

  • Browse To file://./backofficestorage/DomainName/ where DomainName doesn't exist

Result: MBX folder

  • Browse To file://./backofficestorage/DomainName/MBX where DomainName does or doesn't exist

Result empty directory.

  • Browse To file://./backofficestorage/DomainName/TopLevelFolder1 where DomainName doesn't exist

Result command fails.

  • Browse To file://./backofficestorage/DomainName/MBX/User/NON-IPM-SUBTREE

Result lists the top-level folders in the NON-IPM-SUBTREE for this user. The NON-IPM-SUBTREE is not visible in a normal directory listing of //./backofficestorage/DomainName/MBX/UserName. One must specify the NON-IPM-SUBTREE explicitly to get its contents.

  • Browse To file://./backofficestorage/DomainName/TopLevelFolder1/NON-IPM-SUBTREE

Result lists the top-level folders in the NON-IPM-SUBTREE for TopLevelFolder1.


HTTP URL Namespace

The Exchange schema will include properties that have HTTP URLs as values. Currently ExOLEDB does not register support for any part of the http:// namespace.

See the OLD DB 2.5 documentation for the description of how different OLE DB providers may register for different parts of the http:// namespace.


Schema Fields and Namespaces

When accessed through the Exchange OLE DB provider, item property names are scoped using a Uniform Resource Identifier (URI) namespace reference. By convention, each namespace URI falls within either the Uniform Resource Name (URN) or Uniform Resource Locator (URL) scheme. The full name of each property is a concatenation of the namespace URI prefix and the local property name.

An example of a property name using the URN scheme is the "To:" mail header field for messages. The full name of the property when accessed through the Exchange OLE DB provider is:

urn:schemas:mailheader:to

In this case, the namespace for the property is "urn:schemas:mailheader:" (a URI and a URN) and the local name is "to".

An example of the URL scheme is the property used when registering a store event sink to identify the sink's programmatic (ProgID) or class identifier (CLSID):

http://schemas.microsoft.com/exchange/events/SinkClass

In this case, the URI namespace is http://schemas.microsoft.com/exchange/events/ and the local name is SinkClass.


Schema Rowsets

The Exchange OLE DB provider supports the following schema rowsets:

  • CATALOGS
  • COLUMNS
  • PROVIDER_TYPES
  • TABLES

Catalog schema exists for any given database (any legal URL) within an Exchange MDB. The schema is accessed in the typical OLE DB 2.5 manner by creating a session (with a URL scope) and then using the IDBSchemaRowset interface.


CATALOG schema

CATALOG schema uses the TABLES schema definitions. For CATALOG schema the TABLE_CATALOG refers to the folder name, and the TABLE_NAME refers to the full URL to the parent folder. When using the TABLE_CATALOG as CATALOG schema the term "table" can be replaced with the term "folder".

The following table lists TABLE_CATALOG changes when used as CATALOG schema.

Column Name | Comments
TABLE_CATALOG | The folder name
TABLE_NAME | The full URL to the parent folder

The definition of a catalog depends on whether the database being accessed is a private database or a public database. For private databases, the database connection string must specify a mailbox (a user name in the URL). The catalog name for such a string is the full mailbox URL, such as http://public.servername.com/user1. For public databases, one must specify a URL to the top-level folder of the MDB. The catalog name for a public database is the URL to the top-level folder, such as http://public.servername.com.

Each folder in a user's mailbox or a top-level folder is a table. (In this context, folder and table are synonymous.) TABLE_NAME is the folder name and TABLE_CATALOG is the full URL to the parent folder. The columns returned for a folder table will depend on the type of the folder. In Outlook, when creating a new folder, you must specify one of the following folder types: mail, appointment, contact, journal, task, or note. Each of these folder types requires a certain set of columns. Thus, the folder type determines the columns returned for a folder table. That is, a "SELECT *" on a folder table will return the default columns corresponding to the folder type.


TABLES schema

The following table lists support for the columns in the TABLES rowset:

Column Name | Comments
TABLE_CATALOG | URL to the parent folder for this table/folder
TABLE_SCHEMA | Always NULL
TABLE_NAME | Required Column, name of the resource
TABLE_TYPE | One of two values: TABLE or VIEW
TABLE_GUID | GUID of table (folder)
DESCRIPTION | Always NULL
TABLE_PROPID | Always NULL
DATE_CREATED | Creation date of the table/view
DATE_MODIFIED | Modification date of the table/view


COLUMNS schema

The following table lists support for the columns in the COLUMNS rowset:

Column Name | Comments
TABLE_CATALOG | URL to parent folder for the table (folder) with this column
TABLE_SCHEMA | Always NULL
TABLE_NAME | Table (folder) name
COLUMN_NAME | Column (property) name
COLUMN_GUID | GUID of column (property)
ORDINAL_POSITION | Supported
COLUMN_HASDEFAULT | VARIANT_FALSE
COLUMN_DEFAULT | Always NULL
COLUMN_FLAGS | DBCOLUMNFLAGS values supported: CACHEDEFERRED, ISLONG, ISNULLABLE, MAYBENULL, WRITEUNKNOWN
IS_NULLABLE | Always VARIANT_TRUE
DATA_TYPE | See PROVIDER_TYPES
TYPE_GUID | Always NULL
CHARACTER_MAXIMUM_LENGTH | Supported
CHARACTER_OCTET_LENGTH | Supported
NUMERIC_SCALE | Supported
DATETIME_PRECISION | Supported
CHARACTER_SET_CATALOG | Always NULL
CHARACTER_SET_SCHEMA_DBTYPE_WSTR | Always NULL
CHARACTER_SET_NAME | Always NULL
COLLATION_CATALOG | Always NULL
COLLATION_SCHEMA | Always NULL
COLLATION_NAME | Always NULL
DOMAIN_CATALOG | Always NULL
DOMAIN_SCHEMA | Always NULL
DOMAIN_NAME | Always NULL
DESCRIPTION | Always NULL – see properties on tables (folders)


PROVIDER_TYPES schema

The following table lists support for provider types:

Data Type | Supported (Y/N)
DBTYPE_EMPTY | N
DBTYPE_NULL | Y
DBTYPE_I2 | Y
DBTYPE_I4 | Y
DBTYPE_R4 | Y
DBTYPE_R8 | Y
DBTYPE_CY | Y
DBTYPE_DATE | Y
DBTYPE_BSTR | Y
DBTYPE_DISPATCH | N
DBTYPE_ERROR | N
DBTYPE_BOOL | Y
DBTYPE_VARIANT | Y
DBTYPE_IUNKNOWN | N
DBTYPE_DECIMAL | Y
DBTYPE_UI1 | Y
DBTYPE_ARRAY | Y
DBTYPE_BYREF | Y
DBTYPE_I1 | Y
DBTYPE_UI2 | Y
DBTYPE_UI4 | N
DBTYPE_I8 | Y
DBTYPE_UI8 | N
DBTYPE_GUID | N
DBTYPE_VECTOR | Y
DBTYPE_RESERVED | N
DBTYPE_BYTES | Y
DBTYPE_STR | Y
DBTYPE_WSTR | Y
DBTYPE_NUMERIC | Y
DBTYPE_UDT | N
DBTYPE_DBDATE | Y
DBTYPE_DBTIME | Y
DBTYPE_DBTIMESTAMP | Y
DBTYPE_FILETIME | Y
DBTYPE_HCHAPTER | N
DBTYPE_PROBVARIANT | Y
DBTYPE_VARNUMERIC | Y

See MAPI Data Types for MAPI conversion information.


Data Conversions

The Exchange OLE DB provider supports data types based on OLE DB DBTYPEs. However, since the Web Storage System does not support unsigned integers, ExOLEDB converts the unsigned values to signed values. For example, properties of type VT_UI4 (unsigned long) are stored as the MAPI type PT_I4 (signed long). When the property is queried or enumerated, it is listed in its converted form as a signed long.

Similarly, ExOLEDB does not support conversions between vector types (for example, converting from DBVECTOR_I4 to DBVECTOR_I8, DB_UI8 to DB_I8, DBTIME or DBTIMESTAMP to DBFILETIME). Attempting to convert between vector types will return the HRESULT value E_CANTCONVERTVALUE.


MAPI Data Types

Most MAPI data types map one-to-one to a corresponding OLE DB data type. The one exception is the MAPI multi-value data type: except in the case of a binary property, this maps to the OLE DB DBVECTOR data type. DBVECTOR ExOLEDB deals with each binary property and multi-value binary property on a case-by-case basis. For example, free/busy data is stored as a multi-valued binary. ExOLEDB will return this data as a stream.


Structured Documents

Structured documents are not supported in ExOLEDB. MIME documents are fully supported in CDO via the IBodyPart and IBodyParts interfaces.


Event Log Events

The Exchange OLE DB provider provides the following events for the Microsoft® Windows® 2000 Application event log:

Severity | Symbol | Description
Informational | EXOLEDB_SERVICE_STARTUP | Microsoft Exchange OLE DB has successfully started.
Informational | EXOLEDB_SERVICE_SHUTDOWN | Microsoft Exchange OLE DB has successfully shutdown.


Performance Monitor Counters

The implementation must provide performance monitor counters that allow an administrator or performance analyst to easily discover performance issues in a particular deployment. For the core OLE DB functions, these performance monitor counters will be the same as the store performance monitor counters. For OLE DB specific implementation such as the event interface, the OLE DB layer in the store will support perfmon counters that allow an administrator or performance analyst to easily discover how an out-of-process sink affects the performance of the overall system. In addition, the OLE DB provider can instantiate performance monitor counters by a virtual server, similar to what is done by DAV, SMTP, and NNTP.

The following performance monitor counters are supported (all rate counters are "per second" counters):

  • Cache Size Bytes (for Rowsets and other applicable objects)
  • Row Bindings rate
  • Row Bindings total
  • Rows Modified rate
  • Rows Modified total
  • Rowsets Opened rate
  • Rowsets Opened total
  • Active TDataSources
  • Active TSessions
  • Transactions Started rate
  • Transactions Started total
  • Transactions Aborted rate
  • Transactions Aborted total
  • Transactions Committed rate
  • Transactions Committed total


Data Types and Mappings

A rich set of single and multi-valued data types are provided for item properties in the Web Storage System. The following table lists each type using the XML-Data representation. The next table lists the mapping between these data types and the types presented using OLE DB and Messaging Application Programming Interface (MAPI).

Type (XML) | Description
boolean | A Boolean value, either True or False. In an XML string, this value is either 1 for True, or 0 for False.
i2 mv.i2 | 2-byte integer.
int mv.int | 4-byte integer.
i8 mv.i8 | 8-byte integer.
dateTime.tz mv.dateTime.tz | Date and Time.
r4 mv.r4 | 4-byte floating point number.
fixed.14.4 mv.fixed.14.4 | Fixed floating point number.
float mv.float | Floating point number.
uuid mv.uuid | Universally Unique Identifier in string format.
string mv.string | 2-byte character string (Unicode)
bin.base64* mv.bin.base64* | Binary data (base64 encoded)

The following table lists the mappings between types in OLE DB (Exchange OLE DB Provider), MAPI, and XML (WebDAV).

Data Types and Mappings

XML-Data Type | OLE DB Type | MAPI Type
boolean | DBTYPE_BOOL | PT_BOOLEAN
i2 mv.i2 | DBTYPE_I2 DBTYPE_ARRAY | DBTYPE_I2 | PT_I2 PT_MV_I2
int mv.int | DBTYPE_I4 DBTYPE_ARRAY | DBTYPE_I4 | PT_LONG PT_MV_LONG
i8 mv.i8 | DBTYPE_I8 DBTYPE_ARRAY | DBTYPE_I8 | PT_I8 PT_MV_I8
dateTime.tz mv.dateTime.tz | DBTYPE_FILETIME DBTYPE_ARRAY | DBTYPE_FILETIME | PT_SYSTIME PT_MV_SYSTIME
dateTime.tz mv.dateTime.tz | DBTYPE_FILETIME DBTYPE_ARRAY | DBTYPE_FILETIME | PT_APPTIME PT_MV_APPTIME
r4 mv.r4 | DBTYPE_R4 DBTYPE_ARRAY | DBTYPE_R4 | PT_R4 PT_MV_R4
fixed.14.4 mv.fixed.14.4 | DBTYPE_CY DBTYPE_ARRAY | DBTYPE_CY | PT_CURRENCY PT_MV_CURRENCY
float mv.float | DBTYPE_DOUBLE DBTYPE_ARRAY | DBTYPE_DOUBLE | PT_DOUBLE PT_MV_DOUBLE
uuid mv.uuid | DBTYPE_GUID DBTYPE_ARRAY | DBTYPE_GUID | PT_CLSID PT_MV_CLSID
string mv.string | DBTYPE_WSTR DBTYPE_ARRAY | DBTYPE_WSTR | PT_UNICODE PT_MV_UNICODE
string* mv.string* | DBTYPE_STR DBTYPE_ARRAY | DBTYPE_STR | PT_STRING8 PT_MV_STRING8
bin.base64* mv.bin.base64* | DBTYPE_BYTES DBTYPE_ARRAY | DBTYPE_BYTES | PT_BINARY PT_MV_BINARY
Not Supported | DBTYPE_ERROR | PT_ERROR
Not Supported | DBTYPE_NULL | PT_NULL
Not Supported | DBTYPE_IUNKNOWN | PT_OBJECT
Not Supported | Not Supported | PT_UNSPECIFIED


XML-Data Data Types

The Web Storage System WebDAV protocol service translates property values from an XML-Data type to the MAPI/OLE DB data type when received from a client, and converts the property values from a MAPI/OLE DB data type to an XML-Data type when transmitted over the network to a client. The following sections outline how certain special cases are dealt with when using the WebDAV protocol.

Multi-valued Properties

Multi-valued properties are identified with mv. prefixed to the single type name in the XML-Data representation. For example, a multi-valued string would be expressed as "mv.string". This rule applies for all the supported data types.

Binary Properties

Binary properties are identified with the PT_BINARY MAPI data type and the DBTYPE_BYTES OLE DB data type in the store. When transmitted over WebDAV, binary data is encoded using the base64 mechanism without the extra line breaks after each block of 64 outputted characters. The XML-Data type for binary data transmitted over WebDAV is "bin.base64". When binary properties are set using the WebDAV protocol, the client transmits the data in base64-encoded format. The Web Storage System decodes the data and puts it in the store.

Binary multi-valued properties have the type PT_MV_BINARY MAPI type and the DBTYPE_ARRAY | DBTYPE_BYTES OLE DB type. When transmitted, each value is encoded using base64, and the XML-Data type is set to "mv.bin.base64". The reverse process is performed when a client submits a multi-valued binary property using the WebDAV protocol.

String Properties

Three MAPI and two OLE DB data types are provided when working with string properties:

Type | Description
PT_STRING8 (MAPI) DBTYPE_STR (OLE DB) | A null-terminated 8-bit character string. These strings can be encoded using the variety of single and multi-byte character encodings supported by Microsoft® Windows®.
PT_UNICODE (MAPI) DBTYPE_WSTR / DBTYPE_BSTR | A null-terminated 16-bit, Unicode character string.
PT_TSTRING (MAPI) | Used in C/C++ projects only. If UNICODE is defined for the project, the string is stored as PT_UNICODE, otherwise as PT_STRING8.

When preparing string properties for transmission over the network using WebDAV, strings stored as PT_STRING8 are converted from the local single or multi-byte character encoding to Unicode characters and then transmitted to the client. Clients specify the string character encoding within the XML processing instruction transmitted over WebDAV when sending string properties over WebDAV, for example in a PROPPATCH command.

Multi-valued strings are identified using the XML-Data type "mv.string".


Event Interfaces

Web Storage System events fall into three categories: synchronous events, asynchronous events, and system events. Each event type has interfaces and methods that you can use to build procedures that react to Web Storage System events. This section lists the Web Storage System event interfaces and methods.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


IAsyncNotify Interface

This interface enables an asynchronous event handler to notify Exchange 2000 Server that it has finished processing an event.

Method | Function
Completed | Called by an asynchronous event sink to notify the Web Storage System that processing of the event is no longer pending and is now completed.

Remarks

When handling an asynchronous event using a COM handler, it is best for the handler to create a new thread to process the event and immediately return S_PENDING. Once the handler has finished processing it then calls back to the store with IAsyncNotify::Completed.

This is because COM calls are synchronous, therefore the thread the store uses to call the handler is blocked while it waits for the method call to return. Thus best practice for scalability is for the handler to return as soon as possible and process the event asynchronously. When a handler returns S_PENDING, the store does not remove the event from its events queue. When the handler calls back with IAsyncNotify::Completed, only then does the store remove the event from its events queue. This allows the store to guarantee events are processed, without blocking its own threads to wait for the processing to complete.

You can get the IAsyncNotify interface from the IExStoreEventInfo Interface that is passed to your Asynchronous sink.


IAsyncNotify::Completed

This method allows an asynchronous event handler to notify Exchange that it has finished processing an event.

[Visual Basic, VBScript]
Sub Completed()
[C++]
HRESULT Completed();
[IDL]
HRESULT Completed();

Return Value

This is a call you make to the store. The return value is not defined.

Remarks

In your COM event sinks you can process asynchronous events with the following steps.

  1. Obtain the IAsyncNotify interface from the IExStoreEventInfo Interface that is passed to your Asynchronous sink.
  2. Create a new thread to handle the event.
  3. Return S_PENDING.
  4. Call IAsyncNotify Completed from your new process when you are finished handling the event.

If you return S_PENDING from your event notification and do not call IAsyncNotify Completed, Exchange will notify you of this event again when the store is next restarted.


ICreateRegistration Interface

This optional interface gives you further control of registration for events. It also provides means of notification when a registration item is modified, moved, copied, or replicated.

Registration Event (Method) | Function
Register | Automatically called by the event system when an event registration item is saved to the store

Remarks

When an event registration item is registered (saved the first time), modified and saved, copied, moved, or replicated, Microsoft® Exchange 2000 Server automatically queries your sink for this interface. If the interface is available, Exchange 2000 Server then calls ICreateRegistration::Register.


ICreateRegistration::Register

This method allows you to deny event registration requests or respond to event registration items when they are modified, moved, copied, or replicated.

[Visual Basic, VBScript]
Sub Register(
   pEventInfo As IExStoreEventInfo,
   bstrURLItem As String,
   lFlags As Long
   phr As Long
   )
[C++]
HRESULT Register(
   IExStoreEventInfo* pEventInfo,
   BSTR bstrURLItem,
   LONG lFlags,
   LONG* phr
   );
[IDL]
HRESULT Register(
   [in] IExStoreEventInfo* pEventInfo,
   [in] BSTR bstrURLItem,
   [in] LONG lFlags,
   [out,retval] LONG* phr
   );
pEventInfo
A pointer to an IExStoreEventInfo interface that can be used to obtain further event information, such as the registration item.
bstrURLItem
A string containing the URL to the registration item seeking to be registered.
lFlags
Flags to indicate what is occurring to the registration item.
Decimal Value | C++ Enum Equivalent | Description
1 | EVT_NEW_ITEM | The registration item is newly created (a new request).
4 | EVT_REPLICATED_ITEM | The registration item is being replicated from another location.
256 | EVT_MOVE | The registration item is being moved.
512 | EVT_COPY | The item registration item is being copied.

If no flag is set then the item is being resaved to the same location.

phr
Return value: S_OK if registration is allowed, S_FALSE if registration is denied.

Return Value

The return value is not evaluated. You allow or deny the registration request by setting phr to S_OK or S_FALSE.

Remarks

When an event registration item is saved, copied, moved, or replicated, Exchange 2000 Server automatically queries your event sink for the ICreateRegistration interface and, if available, calls this method.

This method provides a programmatic means to evaluate a new event registration request, as well as, when an event registration item is modified, moved, copied, or replicated. In this method you can access the registration item where the user, and the store item resides.


IExStoreAsyncEvents Interface

The following table describes the asynchronous event methods.

Asynchronous Event (Method) | Function
OnDelete | Fired when a resource is deleted.
OnSave | Fired when a resource is saved.

Remarks

See Asynchronous Events (Notifications) for an explanation of asynchronous events.

See Events and Event Sink Interfaces for more general information about event sinks.

See the IAsyncNotify Interface for information on processing asynchronous events in a COM object.


IExStoreAsyncEvents::OnDelete

This is fired by a store when an item is deleted.

[Visual Basic, VBScript]
Sub OnDelete(
   pEventInfo As IExStoreEventInfo,
   bstrURLItem As String,
   lFlags As Long
   )
[C++]
HRESULT OnDelete(
   IExStoreEventInfo* pEventInfo,
   BSTR bstrURLItem,
   LONG lFlags
   );
[IDL]
HRESULT OnDelete(
   [in] IExStoreEventInfo* pEventInfo,
   [in] BSTR bstrURLItem,
   [in] LONG lFlags
   );
pEventInfo
A pointer to an IExStoreEventInfo interface that can be used to obtain further information related to the event.
bstrURLItem
A string containing the deleted item's URL. The URL item cannot be opened because the item has already been deleted.
lFlags
The following (bitwise AND flags can give you further information about the delete event.
Decimal Value | C++ Enum Equivalent | Description
2 | EVT_IS_COLLECTION | The item being deleted is a collection.
4 | EVT_REPLICATED_ITEM | The item is being replicated from another location.
16 | EVT_SOFTDELETE | The item was moved to the dumpster (soft delete).
32 | EVT_HARDDELETE | The item was permanently deleted (hard delete).
64 | EVT_INITNEW | This flag is set at the first firing of the event. (Useful for initialization purposes. It is set only once during the lifetime of a created event sink.)
256 | EVT_MOVE | The delete was part of a move operation.

Return Value

You return either S_OK or S_PENDING.

If you return S_PENDING, then Exchange expects to receive the IAsyncNotify Completed notification.

Registration Properties

To register for this event, you need to set the registration item's EventMethod property to "OnDelete" (C++ constant = EVT_ON_DELETE).

This event supports the following registration item properties:

Criteria

Enabled

EventMethod

MatchScope

ScriptUrl

SinkClass

See The Event Registration Item for more information on registration properties.

Remarks

This event also fires as the delete part of a move operation. This event does not fire when the item's parent folder is moved or deleted.

See the IAsyncNotify Interface for information on processing asynchronous events in a COM object.


IExStoreAsyncEvents::OnSave

Called by a store when an item is saved.

[Visual Basic, VBScript]
Sub OnSave(
   pEventInfo As IExStoreEventInfo,
   bstrURLItem As String,
   lFlags As Long
   )
[C++]
HRESULT OnSave(
   IExStoreEventInfo* pEventInfo,
   BSTR bstrURLItem,
   LONG lFlags
   );
[IDL]
HRESULT OnSave(
   [in] IExStoreEventInfo* pEventInfo,
   [in] BSTR bstrURLItem,
   [in] LONG lFlags
   );
pEventInfo
A pointer to an IExStoreEventInfo interface that can be used to obtain further information related to the event.
bstrURLItem
A string containing a URL to the new saved item.
IFlags
The following (bitwise AND) flags can give you further information about the save event:
Decimal Value | C++ Enum Equivalent | Meaning
1 | EVT_NEW_ITEM | The item being saved is new.
2 | EVT_IS_COLLECTION | The item being saved is a collection.
4 | EVT_REPLICATED_ITEM | The item is being saved as a result of replication.
8 | EVT_ISDELIVERED | The item is being saved as the result of message delivery.
64 | EVT_INITNEW | This flag is set at the first firing of the event. (Useful for initialization purposes. It is set only once during the lifetime of a created event sink.)
256 | EVT_MOVE | The item was moved over resulting in an implicit save.
512 | EVT_COPY | The item was copied over resulting in an implicit save.

Return Value

You return either S_OK or S_PENDING.

If you return S_PENDING, then Exchange expects to receive the IAsyncNotify Completed notification.

Registration Properties

To register for this event, you need to set the registration item's EventMethod property to "OnSave" (C++ constant = EVT_ON_SAVE).

This event supports the following registration item properties:

Criteria

Enabled

EventMethod

MatchScope

ScriptUrl

SinkClass

Remarks

This event is fired when a new item enters the store, when an existing item is saved, and when an item is moved or copied. This event does not fire when the item's parent folder is moved or copied.

See the IAsyncNotify Interface for information on processing asynchronous events in a COM object.


IExStoreSyncEvents Interface

The following table describes the synchronous event methods.

Synchronous Event (Method) | Description
OnSyncDelete | Fired synchronously when an item is deleted from the store.
OnSyncSave | Fired synchronously before an item is saved to the store.

Remarks

See Synchronous Events and Synchronous Event_Details for information about synchronous events.

See Events and Event Sink Interfaces for more general information about event sinks.


IExStoreSyncEvents::OnSyncDelete

Called by a store when an item is being deleted.

[Visual Basic, VBScript]
Sub OnSyncDelete(
   pEventInfo As IExStoreEventInfo,
   bstrURLItem As String,
   lFlags As Long
   )
[C++]
HRESULT OnSyncDelete(
   IExStoreEventInfo  * pEventInfo,
   BSTR bstrURLItem,
   LONG lFlags
   );
[IDL]
HRESULT OnSyncDelete(
   [in] IExStoreEventInfo * pEventInfo,
   [in] BSTR bstrURLItem,
   [in] LONG lFlags
   );
pEventInfo
A pointer to an IExStoreEventInfo interface that can be used to obtain further information related to the event.
bstrURLItem
A string containing a URL to the item that will be deleted upon successful completion of all synchronous events. This item is unlocked when synchronous events have an open transaction on it.
Flags
The following (bitwise AND) flags can give you further information about the delete event:
Decimal Equivalent | C++ Enum Equivalent | Meaning
2 | EVT_IS_COLLECTION | The item being deleted is a collection.
4 | EVT_REPLICATED_ITEM | The item is being replicated from another location.
16 | EVT_SOFTDELETE | The item has been moved to the dumpster (soft delete).
32 | EVT_HARDDELETE | The item has left the store MDB (hard delete).
256 | EVT_MOVE | The item was moved over resulting in an implicit delete.
64 | EVT_INITNEW | This flag is set at the first firing of the event. (Useful for initialization purposes. It is set only once during the lifetime of a created event sink.)
33554432 | EVT_SYNC_COMMITTED | Synchronous committed event.
67108864 | EVT_SYNC_ABORTED | Synchronous aborted event.
1073741824 | EVT_INVALID_URL | The URL passed to the sink is invalid.
2147483648 | EVT_ERROR | An error occurred in the event.

Return Value

The return value is not evaluated.

Registration Properties

To register for this event, you need to set the registration item's EventMethod property to "OnSyncDelete" (C++ constant = EVT_ON_SYNC_DELETE).

This event supports the following registration item properties:

Criteria

Enabled

EventMethod

MatchScope

Priority

ScriptUrl

SinkClass

Remarks

This event is fired when an item is deleted from the store, or when an item is moved in the store. This event is not fired when the item's parent folder is moved or deleted.

The OnDelete event uses the EVT_HARDDELETE and EVT_SOFTDELETE flags to distinguish between hard and soft deletes. A soft delete is defined as a delete that moves an item into the dumpster the deleted subfolder within each folder. A hard delete is defined as a delete in which an item is completely removed from the store.

Aborting the transaction associated with this event will prevent the item from being deleted. If you abort an event that is the result of a move, then both the save and delete steps of the move will be aborted. This means that the original item will not be deleted and the new item will not be saved.

See Synchronous Events and Synchronous Event_Details for more information.


IExStoreSyncEvents::OnSyncSave

Called by a store event source when an item is being saved.

[Visual Basic, VBScript]
Sub OnSyncSave(
   pEventInfo As IExStoreEventInfo,
   bstrURLItem As String,
   lFlags As Long
   )
[C++]
HRESULT OnSyncSave(
   IExStoreEventInfo  * pEventInfo,
   BSTR bstrURLItem,
   LONG lFlags
   );
[IDL]
HRESULT OnSyncSave(
   [in] IExStoreEventInfo * pEventInfo,
   [in] BSTR bstrURLItem,
   [in] LONG lFlags
   );
pEventInfo
A pointer to an IExStoreEventInfo interface that can be used to obtain further information related to the event.
bstrURLItem
A string containing the URL of the item on which the event is occurring. This value is only valid if OLEDB or DAV created the item; that is if the client set has the property PR_URL_COMP_NAME.
lFlags
The following (bitwise AND) flags can give you further information about the save event. You can also use hexidecimal equivalents of the decimal values.
Decimal Value | C++ Enum Equivalent | Meaning
1 | EVT_NEW_ITEM | The item being saved is new.
2 | EVT_IS_COLLECTION | The item being saved is a collection.
4 | EVT_REPLICATED_ITEM | The item is being saved as a result of replication.
8 | EVT_IS_DELIVERED | The item is being saved as the result of message delivery.
64 | EVT_INITNEW | This flag is set at the first firing of the event. (Useful for initialization purposes. It is set only once during the lifetime of a created event sink.)
256 | EVT_MOVE | The item being saved is being moved.
512 | EVT_COPY | The item being saved is being copied.
1024 | EVT_DRAFT_CREATE | The item being saved is a newly created draft.
2048 | EVT_DRAFT_SAVE | The item being saved is a draft.
4096 | EVT_DRAFT_CHECKIN | The item being saved is a draft check-in.
16777216 | EVT_SYNC_BEGIN | Synchronous begin event.
33554432 | EVT_SYNC_COMMITTED | Synchronous committed event.
67108864 | EVT_SYNC_ABORTED | Synchronous aborted event.
536870912 | EVT_INVALID_SOURCE_URL | The Source URL could not be obtained during a move operation.
1073741824 | EVT_INVALID_URL | The URL passed to the sink is invalid.
2147483648 | EVT_ERROR | An error occurred in the event.

Return Value

The return value is not evaluated.

Registration Properties

To register for this event, you need to set the registration item's EventMethod property to "OnSyncSave" (C++ constant = EVT_ON_SYNC_SAVE).

This event supports the following registration item properties:

Criteria

Enabled

EventMethod

MatchScope

Priority

ScriptUrl

SinkClass

See The Event Registration Item for more information on registration properties.

Remarks

This event is fired prior to the item being saved. This event is fired when a new item enters the store, when an existing item is saved, and when an item is moved or copied. This event does not fire when the item's parent folder is moved or copied.

Aborting the transaction associated with this event will cause the item to not be saved. If the event fired as a result of a move, aborting the transaction will abort the entire move; the original item will not be deleted and the new item will not be saved.

Synchronous events are always called twice, once for the transaction and once for the commit or abort action. See Synchronous Events for more information.


IExStoreSystemEvents Interface

The IExStoreSystemEvents interface contains events that provide information pertaining to system activities in the store. It also includes the timer event.

The following table describes the system event methods.

System Event (Method) | Description
OnTimer | Called on a registration-specified time period.
OnMDBStartUp | Called asynchronously when an MDB is started.
OnMDBShutdown | Called asynchronously when an MDB is stopped.

See System Events for an explanation of system events.

See Events and Event Sink Interfaces for more general information about event sinks.


IExStoreSystemEvents::OnTimer

Called after a specific interval of time.

[Visual Basic, VBScript]
Sub OnTimer(
   bstrURLItem As String,
   lFlags As Long
   )
[C++]
HRESULT OnTimer(
   BSTR bstrURLItem,
   LONG lFlags
   );
[IDL]
HRESULT OnTimer(
   [in] BSTR bstrURLItem,
   [in] LONG lFlags
   );
bstrURLItem
A URL to the event registration item.
lFlags
The following (bitwise AND) flags can give you further information about the system event:
Decimal Value | C++ Enum Equivalent | Meaning
64 | EVT_INITNEW | This flag is set at the first firing of the event. (Useful for initialization purposes. It is set only once during the lifetime of a created event sink.)

Return Value

The return call is not evaluated.

Registration Properties

To register for this event, you need to set the registration item's EventMethod property to "OnTimer" (C++ constant = EVT_ON_TIMER).

This event supports the following registration item properties:

Enabled

EventMethod

ScriptUrl

SinkClass

TimerExpiryTime

TimerInterval

TimerStartTime

See The Event Registration Item for more information on registration properties.

Remarks

This method is called for the time or time interval specified in the registration item.

Note The store may not invoke this sink if the server is not running when the specified time elapses. For example, if a sink registers for notification at 11:00 A.M. and the service goes down at 10:55 A.M. and comes back up at 11:05 A.M., the sink may not be called.


IExStoreSystemEvents::OnMDBStartUp

Called on event sinks whenever a store starts functioning.

[Visual Basic, VBScript]
Sub OnMDBStartUp(
   bstrMDBGuid As String,
   bstrMDBName As String
   lFlags As Long
   )
[C++]
HRESULT OnMDBStartUp(
   BSTR bstrMDBGuid,
   BSTR bstrMDBName,
   LONG lFlags
   );
[IDL]
HRESULT _OnMDBStartUp(
   [in] BSTR bstrMDBGuid,
   [in] BSTR bstrMDBName,
   [in] LONG lFlags
   );
bstrMDBGuid
String containing the GUID of the MDB being started.
bstrMDBName
String containing the name of the MDB being started.
lFlags
The following (bitwise AND) flags can give you further information about the system event:
Decimal Value | C++ Enum Equivalent | Meaning
64 | EVT_INITNEW | This flag is set at the first firing of the event. (Useful for initialization purposes. It is set only once during the lifetime of a created event sink.)

Return Value

The return value is not evaluated.

Registration Properties

To register for this event, you need to set the registration item's EventMethod property to "OnMDBStartUp" (C++ constant = EVT_ON_MDB_STARTUP).

This event supports the following registration item properties:

Enabled

EventMethod

SinkClass

Remarks

The OnMDBStartUp event is called asynchronously whenever an MDB is started.


IExStoreSystemEvents::OnMDBShutDown

Called on event sinks whenever a store is shut down.

[Visual Basic, VBScript]
Sub OnMDBStartUp(
   bstrMDBGuid As String,
   lFlags As Long
   )
[C++]
HRESULT OnMDBStartUp(
   BSTR bstrMDBGuid,
   LONG lFlags
   );
[IDL]
HRESULT _OnMDBStartUp(
   [in] BSTR bstrMDBGuid,
   [in] LONG lFlags
   );
bstrMDBGuid
String containing the GUID of the MDB being stopped.
lFlags
The following (bitwise AND) flags can give you further information about the system event:
Decimal Value | C++ Enum Equivalent | Meaning
64 | EVT_INITNEW | This flag is set at the first firing of the event. (Useful for initialization purposes. It is set only once during the lifetime of a created event sink.)

Return Value

Returns S_OK if the call succeeds.

Registration Properties

To register for this event, you need to set the registration item's EventMethod property to "OnMDBShutDown" (C++ constant = EVT_ON_MDB_SHUTDOWN).

This event supports the following registration item properties:

Enabled

EventMethod

SinkClass

Remarks

The OnMDBShutDown event is called asynchronously whenever an MDB is stopped.


IExStoreEventInfo Interface

This is a support interface that is passed to every OLE DB store event sink. It is used to retrieve event information and control the event transaction.

Member Summary

Method | Description
Abort | Aborts the event transaction if the event is synchronous.
GetEventItem | Returns an interface on the item that triggered the event.
GetEventSession | Returns an interface on the ADO/OLE DB Session object under which the event is executing.
RemoteGetEventItem | Returns an interface on the remote item that triggered the event.
RemoteGetEventSession | Returns an interface on the remote ADO/OLE DB Session object under which the event is executing.

Note URLMapper is not a castable interface implemented by this interface. URLMapper is an independently creatable object. Additionally, in compiled Visual Basic code you must use CreateObject ("EXOLEDB.URLMapper").

See IExStoreDispEventInfo for equivalent methods for Microsoft® Visual Basic® and scripts.


IExStoreEventInfo::Abort

Aborts the event transaction if the event is synchronous.

[Visual Basic,VBScript]
Not applicable (See Remarks)
[C++]
HRESULT Abort(LONG lErrorCode);
[IDL]
HRESULT Abort([in, defaultvalue(0)] LONG lErrorCode);
lErrorCode
The error code you can return to the event source to indicate the reason for the abort. See Remarks.

Return Value

This method returns S_OK if the call succeeds.

Remarks

This method aborts the transaction if the event is synchronous. It is not valid for asynchronous or system events.

When aborting the transaction for reasons other than programmatic failures, set the LErrorCode flag to E_ABORT.

See IExStoreDispEventInfo::AbortChange for the equivalent method for Visual Basic and scripts.


IExStoreEventInfo::GetEventSession

Returns the requested interface on the OLE DB Session object under which the event is executing.

[Visual Basic,VBScript]
Not applicable (See Remarks)
[C++]
HRESULT GetEventSession (
   REFIID riid,
   IUnknown** ppSession
   );
[IDL]
HRESULT GetEventSession (
   [in] REFIID riid,
   [out] IUnknown** ppSession
   );
riid
The interface identifier (IID) of the requested interface.
ppSession
On successful return, the passed address contains an IUnknown object reference to the OLE DB Session object under which the event is executing.

Return Value

This method returns S_OK if the call succeeds.

Remarks

This method returns the requested interface on the OLE DB Session object under which the event is executing. For synchronous events, the event session executes within a local transaction. For asynchronous events, the object is implicitly created using an IBindResource::Bind call. The object is created within the security context of the default user. Access is limited to the event item.

See the IExStoreDispEventInfo Interface for related methods for Visual Basic and scripts.


IExStoreEventInfo::GetEventItem

This method returns the requested interface on the OLE DB Row object that triggered the event.

[Visual Basic, VBScript]
Not applicable (See Remarks)
[C++]
HRESULT GetEventItem (
   REFIID riid,
   DWORD* pdwBindStatus,
   IUnknown** ppunkEventItem
   );
[IDL]
HRESULT GetEventItem (
   [in]REFIID riid,
   [out]DWORD* pdwBindStatus,
   [out]IUnknown** ppunkEventItem
   );
riid
The interface identifier (IID) of the interface on the item to return in the third argument.
pdwBindStatus
The returned status code.
ppunkEventItem
On successful return, the address passed contains the IUnknown object reference on the item that triggered the event.

Return Value

This method returns S_OK if successful.

Remarks

For synchronous events, this item is created within a transaction. For asynchronous events the object is created through the IBindResource::Bind call. The object is created within the security context of the default user. Access is limited to the event item.

This method is functionally equivalent to the EventRecord method on the IExStoreDispEventInfo dual interface. When working with Microsoft® Visual Basic® and scripting languages, you need to make sure to retrieve this OLE Automation compatible interface from the passed object.

See the IExStoreDispEventInfo Interface for related methods for Visual Basic and scripts.


IExStoreEventInfo::RemoteGetEventItem

This method returns the requested interface on the remote OLE DB Row object that triggered the event.

[Visual Basic, VBScript]
Not applicable (See Remarks)
[C++]
HRESULT RemoteGetEventItem (
   REFIID riid,
   DWORD* pdwBindStatus,
   IUnknown** ppunkEventItem
   );
[IDL]
HRESULT RemoteGetEventItem (
   [in]REFIID riid,
   [out]DWORD* pdwBindStatus,
   [out]IUnknown** ppunkEventItem
   );
riid
The interface identifier (IID) of the interface on the item to return in the third argument.
pdwBindStatus
The returned status code.
ppunkEventItem
On successful return, the address passed contains the IUnknown object reference on the remote item that triggered the event.

Return Value

This method returns S_OK if successful.

Remarks

For synchronous events, this item is created within a transaction. For asynchronous events, the object is created through the IBindResource::Bind call. The object is created within the security context of the default user. Access is limited to the event item.

This method is functionally equivalent to the EventRecord method on the IExStoreDispEventInfo dual interface. When working with Microsoft® Visual Basic® and scripting languages, you need to make sure to retrieve this OLE Automation compatible interface from the passed object.

See the IExStoreDispEventInfo Interface for related methods for Visual Basic and scripts.


IExStoreEventInfo::RemoteGetEventSession

Returns the requested interface on the remote OLE DB Session object under which the event is executing.

[Visual Basic,VBScript]
Not applicable (See Remarks)
[C++]
HRESULT RemoteGetEventSession (
   REFIID riid,
   IUnknown** ppSession
   );
[IDL]
HRESULT RemoteGetEventSession (
   [in] REFIID riid,
   [out] IUnknown** ppSession
   );
riid
The interface identifier (IID) of the requested interface.
ppSession
On successful return, the passed address contains an IUnknown object reference to the remote OLE DB Session object under which the event is executing.

Return Value

This method returns S_OK if the call succeeds.

Remarks

This method returns the requested interface on the remote OLE DB Session object under which the event is executing. For synchronous events, the event session executes within a transaction. For asynchronous events, the object is implicitly created using an IBindResource::Bind call. The object is created within the security context of the default user. Access is limited to the event item.

See the IExStoreDispEventInfo Interface for related methods for Visual Basic and scripts.


IExStoreDispEventInfo Interface

This is a support interface that can be obtained within every OLE DB store event sink. It is used to retrieve event information and control the event transaction.

Member Summary

Property | Description
AbortChange | Aborts the transaction in which the event is currently executing.
EventConnection | The ADO Connection object under which the event is executing.
EventRecord | The ADO Record object bound to the item that triggered the event.
SourceURL | Gets the original source URL during OnSyncSave event caused by a move.
UserGuid | Gets the GUID of the user who caused this synchronous event.
StoreGuid | Gets the GUID of the store on which this synchronous event occurs.
UserSid | Gets the SID of the user who caused this synchronous event.
Data | Get or Set data.

Remarks

The IExStoreDispEventInfo interface is the OLE Automation compatible version of the IExStoreEventInfo interface. Languages such as Microsoft® Visual Basic® can access the ADO equivalents of the OLE DB object references using the various IExStoreDispEventInfo methods.

The IExStoreDispEventInfo interface is exposed on the same object as the passed IExStoreEventInfo object reference. It can be obtained by calling QueryInterface on the IExStoreEventInfo object reference passed to the sink.

Example

[Visual Basic]
Private Sub IExStoreAsyncEvents_OnSave( _
  ByVal pEventInfo as ExevtsnkLib.IExStoreEventInfo, _
  ByVal bstrURLSource as String, _
  ByVal lFlags as Long _
)

  ' Get OA compatible interface
  Dim iDispEvtInfo as IExStoreDispEventInfo

'In Visual Basic this next line does the QueryInterface
  Set iDispEvtInfo = pEventInfo

  ' Get ADO record for save item
  Dim Rec as ADODB.Record
  Set Rec = iDispEvtInfo.EventRecord
  ' ...
End Sub
© 2000-2001 Microsoft Corporation. All rights reserved.


IExStoreDispEventInfo::AbortChange

This method aborts the transaction in which the synchronous event is currently executing.

[Visual Basic,VBScript]
Sub AbortChange ( lErrorCode as Long )
[C++]
HRESULT AbortChange(LONG lErrorCode);
[IDL]
HRESULT AbortChange(LONG lErrorCode);
lErrorCode
The error code you can return to the event source to indicate the reason for the abort. See Remarks.

Return Value

This method returns S_OK if the call succeeds.

Remarks

This method is only valid for synchronous events that run in the context of an OLE DB local transaction. It is not valid for asynchronous or system events.

When aborting the transaction for reasons other than programmatic failures, set the LErrorCode flag to E_ABORT.


IExStoreDispEventInfo::EventConnection

The ADO Connection object for the current event.

[Visual Basic,VBScript]
Property EventConnection As Object
read-only
[C++]
HRESULT EventConnection (IDispatch** pConnection);
[IDL]
[propget] HRESULT EventConnection(
   [out,retval] IDispatch** pConnection
   );
pConnection [C++,IDL]
Upon successful return, the passed address contains a valid IDispatch object reference on the ADO Connection object used to bind to the store.

Return Value

This method returns S_OK if the call succeeds.

Remarks

This method returns the IDispatch interface pointer for the ADO Connection object created in the context of the event. This method is similar to IExStoreEventInfo::GetEventSession except that OLE Automation compatible ADO objects and interfaces are returned rather than OLE DB objects and interfaces.

For synchronous events, the event session executes within a local transaction. For asynchronous events, the object is implicitly created using an IBindResource::Bind call. The object is created within the security context of the default user. Access is limited to the event item.

Example

[Visual Basic]
Private Sub IExStoreAsyncEvents_OnSave( _
  ByVal pEventInfo as ExevtsnkLib.IExStoreEventInfo, _
  ByVal bstrURLSource as String, _
  ByVal lFlags as Long _
)

  ' Get an OA compatible interface
  Dim iDispEvtInfo as IExStoreDispEventInfo
  Set iDispEvtInfo = pEventInfo

  ' Get the Connection used for the event
  Dim Conn as ADODB.Connection
  Set Conn = iDispEvtInfo.EventConnection
  ' ...
End Sub
© 2000-2001 Microsoft Corporation. All rights reserved.


IExStoreDispEventInfo::EventRecord

The ADO Record object bound to the item that caused the event.

[Visual Basic,VBscript]
Property EventRecord As Object
read-only
[C++]
HRESULT EventRecord(IDispatch** ppRecord);
[IDL]
[propget] HRESULT EventRecord( IDispatch** ppRecord);
pVal [C++,IDL]
On successful return, the passed address contains the IDispatch interface of the ADO Record object bound to the store item that triggered the event.

Return Value

This method returns S_OK if the call succeeds.

Remarks

This method returns the IDispatch interface on the ADO Record object created in the context of the event. This method is similar to the IExStoreEventInfo::GetEventItem method except that OLE Automation compatible ADO objects and interfaces are used rather than OLE DB objects and interfaces.

For synchronous events, the event session executes within a local transaction. For asynchronous events, the object is implicitly created using an IBindResource::Bind call. The object is created within the security context of the default user. Access is limited to the event item.

Example

[Visual Basic]
Private Sub IExStoreAsyncEvents_OnSave( _
  ByVal pEventInfo as ExevtsnkLib.IExStoreEventInfo, _
  ByVal bstrURLSource as String, _
  ByVal lFlags as Long _
)

  ' Get OA compatible interface
  Dim iDispEvtInfo as IExStoreDispEventInfo
  Set iDispEvtInfo = pEventInfo

  ' Get the record that triggered the event
  Dim Rec as ADODB.Record
  Set Rec = iDispEvtInfo.EventRecord
  ' ...
End Sub
© 2000-2001 Microsoft Corporation. All rights reserved.


IExStoreDispEventInfo::SourceURL

The original source URL during an OnSyncSave event that was caused by a move.

[Visual Basic,VBScript]
Property SourceURL as String
read-only
[C++]
HRESULT SourceURL(BSTR* pbstrURL);
[IDL]
HRESULT [propget] SourceURL([out,retval] BSTR* pbstrURL);
pbstrURL [C++,IDL]
For an OnSyncSave event that fired during a move operation, this returns the original source URL of the item that caused the event. For all other events and operations this returns NULL.

Return Value

This method returns S_FALSE if the call fails.

Remarks

This method will contain valid data only during an OnSyncSave event during a move operation. When notified for other events and operations other than a move, it will return a NULL value.


IExStoreDispEventInfo::UserGuid

This method returns the GUID of the user that caused the event to fire.

[Visual Basic,VBscript]
Property UserGuid As String
[C++]
HRESULT UserGuid(GUID** pvarUserGuid);
[IDL]
[propget] HRESULT UserGuid([in,out] GUID** pvarUserGuid);
pvarUserGuid [C++,IDL]
On successful return, the passed address contains the GUID of the user who caused the event to fire.

Return Value

This method returns S_FALSE if the call fails.


IExStoreDispEventInfo::UserSid

This method returns the SID of the user that caused the event to fire.

[Visual Basic,VBscript]
Property UserSid As String
[C++]
HRESULT UserSID(SID** pvarSid);
[IDL]
[propget] HRESULT UserSID([out]SID** pvarSid);
pvarSid [C++,IDL]
On successful return, the passed address contains the security identifier (SID) of the user who caused the event to fire.

Return Value

This method returns S_FALSE if the call fails.


IExStoreDispEventInfo::StoreGuid

This method returns the GUID of the MDB store in which the event fired.

[Visual Basic,VBscript]
Property StoreGuid As String
[C++]
HRESULT StoreGuid(GUID** pvarStoreGuid);
[IDL]
[propget] HRESULT StoreGuid([in,out]GUID** pvarStoreGuid);
pvarStoreGuid[C++,IDL]
On successful return, the passed address contains the GUID of the store in which the event fired.

Return Value

This method returns S_FALSE if the call fails.


IExStoreDispEventInfo::Data

This method handles in-memory data that is stored between the begin phase and the commit/abort phase of a synchronous event.

[Visual Basic, VBScript]
Property Data(plData As Long)
[C++]
HRESULT get_Data(LONG_PTR* plData);
HRESULT put_Data(LONG_PTR plData);
[IDL]
[propget] HRESULT Data([in,out, retval]LONG_PTR* plData);
plData
A pointer to the memory when getting. The memory itself when putting.

Remarks

This method is to be used with synchronous events where you want to save data during the begin phase and retrieve the data during the commit/abort phase.

See SetData and GetData for related methods.

Example

Here is how you would use this from a Visual Basic event sink:

Private Sub IExStoreSyncEvents_OnSyncSave( _
        ByVal pEventInfo As Exoledb.IExStoreEventInfo, _
        ByVal bstrURLItem As String, _
        ByVal lFlags As Long)

    Dim DispInfo As IExStoreDispEventInfo
    Dim lValue as long
    Set DispInfo = pEventInfo
    ...
    'In the begin phase you set data as follows
    DispInfo.Data = lValue

    'In the commit phase you get the data as follows
    lValue = DispInfo.Data

End Sub
© 2000-2001 Microsoft Corporation. All rights reserved.


IExStoreEventLogonInfo Interface

This is a support interface for event sinks to provide information about the user who caused the event, and the store in which the event occurred.

Method | Function
GetStoreGuid | Returns the GUID of the store in which the event was fired.
GetUserID | Returns the GUID of the user who caused the event to fire.
GetUserSID | Returns the SID of the user who caused the event to fire.


IExStoreEventLogonInfo::GetStoreGuid

This method returns the GUID of the MDB store in which the event fired.

[Visual Basic,VBscript]
Not applicable (See Remarks)
[C++]
HRESULT GetStoreGuid(GUID** pGuid);
[IDL]
[propget] HRESULT GetStoreGuid([in,out]GUID** pGuid);
pGuid [C++,IDL]
On successful return, the passed address contains the GUID of the store in which the event fired.

Return Value

This method returns S_FALSE if the call fails.

Remarks

See IExStoreDispEventInfo::StoreGuid for the equivalent method for Visual Basic and scripts.


IExStoreEventLogonInfo::GetUserID

This method returns the GUID of the user that caused the event to fire.

[Visual Basic,VBscript]
Not applicable (See Remarks)
[C++]
HRESULT GetUserID(GUID** pGuid);
[IDL]
[propget] HRESULT GetUserID([in,out] GUID** pGuid);
pGuid [C++,IDL]
On successful return, the passed address contains the GUID of the user who caused the event to fire.

Return Value

This method returns S_FALSE if the call fails.

Remarks

See IExStoreDispEventInfo::UserGuid for the equivalent method for Visual Basic and scripts.


IExStoreEventLogonInfo::GetUserSID

This method returns the SID of the user that caused the event to fire.

[Visual Basic,VBscript]
Not applicable (See Remarks)
[C++]
HRESULT GetUserSID(SID** pGuid);
[IDL]
[propget] HRESULT GetUserSID([out]SID** pGuid);
pGuid [C++,IDL]
On successful return, the passed address contains the security identifier (SID) of the user who caused the event to fire.

Return Value

This method returns S_FALSE if the call fails.

Remarks

See IExStoreDispEventInfo::UserSid for the equivalent method for Visual Basic and scripts.


IExoledbUrlMapper Interface

This is a support interface that allows you to convert store paths between different protocol types.

Method | Function
ExoledbFileUrlToFilePath | Converts a file URL from the ExOLEDB provider to a file path that can be used by Windows® file system APIs.
FilePathToExoledbFileUrl | Converts a file path from the local machine to a "file:" URL supported by the ExOLEDB provider.
FilePathToHttpUrls | Converts a file path from the local machine to a list of HTTP URLs that refer to the same resource.
HttpUrlToFilePath | Converts an HTTP URL to a "file:" file path.


IExoledbUrlMapper::ExoledbFileUrlToFilePath

This method converts a file URL from the ExOLEDB provider to a file path that can be used by Windows file system APIs.

[Visual Basic,VBscript]
Function ExoledbFileUrlToFilePath (
   (bstrExoledbFileUrl As String) As String
[C++]
HRESULT ExoledbFileUrlToFilePath(
   BSTR bstrExoledbFileUrl,
   BSTR* pbstrFilePath);
[IDL]
HRESULT ExoledbFileUrlToFilePath(
   [in] BSTR bstrExoledbFileUrl,
   [out, retval] BSTR* pbstrFilePath);
bstrExoledbFileUrl [C++,IDL]
A "file:" URL supported by the ExOLEDB provider.
pbstrFilePath [C++,IDL]
Pointer to a file path that can be passed to the Windows file system APIs.

Return Value

This method returns S_OK if successful.


IExoledbUrlMapper::FilePathToExoledbFileUrl

This method converts a file path from the local machine to a "file:" URL supported by the ExOLEDB provider.

[Visual Basic,VBscript]
Function FilePathToExoledbFileUrl (
   (bstrFilePath As String) As String
[C++]
HRESULT FilePathToExoledbFileUrl(
   BSTR bstrFilePath ,
   BSTR* pbstrExoledbFileUrl);
[IDL]
HRESULT FilePathToExoledbFileUrl(
   [in] BSTR bstrFilePath
   [out, retval] BSTR* pbstrExoledbFileUrl);
bstrFilePath [C++,IDL]
A local file path to a resource in the Web Storage System.
pbstrExoledbFileUrl [C++,IDL]
Pointer to a "file:" URL that can be passed to an ExOLEDB provider.

Return Value

This method returns S_OK if successful.

Remarks

In C++ the returned BSTR must be freed with SysFreeString.


IExoledbUrlMapper::FilePathToHttpUrls

This method converts a file path from the local machine to a list of HTTP URLs that refer to the same resource.

[Visual Basic,VBscript]
Function FilePathToHttpUrls (
   (bstrFilePath As String) As Variant()
[C++]
HRESULT FilePathToHttpUrls(
   BSTR bstrFilePath ,
   SAFEARRAY(VARIANT)* ppsaHttpUrls);
[IDL]
HRESULT FilePathToHttpUrls(
   [in] BSTR bstrFilePath
   [out, retval] SAFEARRAY(VARIANT)* ppsaHttpUrls);
bstrFilePath [C++,IDL]
A local file path to a resource in the Web Storage System.
ppsaHttpUrls [C++,IDL]
A SAFEARRAY of VARIANTs containing the list of http URLs that refer to the same resource.

Return Value

This method returns S_OK if successful.

Remarks

In C++ the returned SAFEARRAY must be freed with SafeArrayDestroy.


IExoledbUrlMapper::HttpUrlToFilePath

This method converts an HTTP URL to a "file:" file path.

[Visual Basic,VBscript]
Function HttpUrlToFilePath (
   (bstrHttpUrl As String) As String
[C++]
HRESULT HttpUrlToFilePath(
   BSTR bstrHttpUrl ,
   BSTR* pbstrFilePath);
[IDL]
HRESULT HttpUrlToFilePath(
   [in] BSTR bstrHttpUrl
   [out, retval] BSTR* pbstrFilePath);
bstrHttpUrl [C++,IDL]
A fully qualified HTTP URL to the local machine.
pbstrFilePath [C++,IDL]
Pointer to the local file path for the resource to which the HTTP URL refers.

Return Value

This method returns S_OK if successful.

Remarks

In C++ the returned BSTR must be freed with SysFreeString.


IGetSourceURL Interface

This is a support interface for use in OnSyncSave events. It is used to get the URL of the source row.

Method | Function
GetSourceURL | Returns the URL of the source row.

See IExStoreDispEventInfo for equivalent methods for Visual Basic and scripts.


IGetSourceURL::GetSourceURL

The original source URL during an OnSyncSave event that was caused by a move.

[Visual Basic,VBscript]
Not applicable (See Remarks)
[C++]
HRESULT GetSourceURL(BSTR* pbstrURL);
[IDL]
[propget] HRESULT GetSourceURL(BSTR* pbstrURL);
pbstrURL [C++,IDL]
For an OnSyncSave event that fired during a move operation, this returns the original source URL of the item that caused the event. For all other events and operations this returns NULL.

Return Value

This method returns S_FALSE if the call fails.

Remarks

This method will contain valid data only during an OnSyncSave event during a move operation. When notified for other events and operations other than a move, it will return a NULL value.

See IExStoreDispEventInfo::SourceURL for an equivalent method for Visual Basic and scripts.


IExStoreEventRegistrationURL Interface

This is a support interface used to return the URL for the event registration item.

Method | Function
EventRegistrationURL | Returns a pointer to a string containing the URL of the event registration item.


IExStoreEventRegistrationURL::EventRegistrationURL

This method returns the URL of the event registration item.

[Visual Basic,VBscript]
Function EventRegistrationURL As String
read-only
[C++]
HRESULT EventRegistrationURL(BSTR* pbstrURL);
[IDL]
[propget] HRESULT EventRegistrationURL(BSTR* pbstrURL);
pbstrURL [C++,IDL]
On successful return, contains a pointer to the URL of the event registration item.

Return Value

This method returns S_FALSE if the call fails.

Remarks

See The Event Registration Item for related information.


IStoreGuidFromURL Interface

Get the MDB GUID from the given URL.

Method | Function
StoreGuidFromURL | Returns the GUID of the store that contains the item specified by the URL.


IStoreGuidFromURL::StoreGuidFromURL

This method returns the GUID of the store that contains the item specified by the URL.

[Visual Basic,VBscript]
Function StoreGuidFromURL As String
read-only
[C++]
HRESULT StoreGuidFromURL(BSTR* pbstrURL);
[IDL]
[propget] HRESULT StoreGuidFromURL(BSTR* pbstrURL);
pbstrURL [C++,IDL]
On successful return, contains the GUID of the store.

Return Value

This method returns S_FALSE if the call fails.

Remarks

This method is useful when the store GUID is required for registration, such as when registering for MDB-wide events.

For CoClass information, see the StoreGuidFromURL CoClass.


IUserData Interface

This interface is used to persist data for the duration of the synchronous event (from the begin phase to the commit/abort phase).

Method | Function
GetData | Retrieve in-memory data that was set with SetData.
SetData | Set in-memory data to be retrieved later with GetData.

Remarks

These methods are to be used with synchronous events where you wish to save data during the begin phase and retrieve the data during the commit/abort phase.

IUserData is not a dual interface. See IExStoreDispEventInfo for equivalent methods for Visual Basic and scripts.


IUserData::GetData

This method retrieves a pointer to data that was set with SetData.

[Visual Basic, VBScript]
Not applicable (See Remarks)
[C++]
HRESULT GetData(LONG_PTR* plData);
[IDL]
[propget] HRESULT GetData(LONG_PTR* plData);
plData
A pointer that was stored to memory using SetData.

Remarks

This method is to be used with synchronous events where you wish to save data during the begin phase and retrieve the data during the commit/abort phase.

See IExStoreDispEventInfo::Data for an equivalent method for Visual Basic and scripts.


IUserData::SetData

This method sets data into memory that can be retrieved later using GetData.

[Visual Basic, VBScript]
Not applicable (See Remarks)
[C++]
HRESULT SetData(LONG_PTR plData);
[IDL]
[propget] HRESULT SetData(LONG_PTR plData);
plData
A pointer that is saved in memory and available with GetData.

Remarks

This method is to be used with synchronous events where you wish to save data during the begin phase and retrieve the data during the commit/abort phase.

See IExStoreDispEventInfo::Data for an equivalent method for Visual Basic and scripts.


WebDAV Reference

The WebDAV protocol is an extension to Hypertext Transfer Protocol (HTTP) that you can use to build Web applications that are writable. Using WebDAV protocol methods, you can create, copy, or move resources in the Web Storage System through HTTP.

This section contains the following topics:

Web Storage System WebDAV Protocol

WebDAV Protocol Errors

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Web Storage System WebDAV Protocol Reference

Platform SDK: Exchange 2000 Server

Web Storage System WebDAV Protocol

The Request for Comments (RFC) 2518 specification defines extensions to the Hypertext Transfer Protocol 1.1 (HTTP/1.1), which is defined in RFC 2616. The extensions include a new set of protocol methods and request headers used to move, copy, delete, and create collections of resources. Additionally, clients can set and get properties about resources along with the resource content itself.

The extensions relating to getting and setting properties require a rich format for data transfer. RFC 2518 defines the Extensible Markup Language (XML) 1.0 as the format for wire data transfer. Additionally, the Namespaces in XML are required to provide scope for property names.

See Constructing WebDAV Requests with XMLDOM for an example using WebDAV and the XMLHTTP object.

The following additional protocol methods are defined by the WebDAV protocol extensions to HTTP 1.1:

Method | Description
COPY | Copy a resource at one local URL to another local URL.
DELETE | Delete a resource at a local URL.
MOVE | Move a resource at one local URL to another local URL.
MKCOL | Create a collection of resources.
PROPFIND | Request properties for a resource at a local URL.
PROPPATCH | Set properties for a resource at a local URL.
PROPERTYUPDATE | Updates a property value, including a deletion.
SEARCH | Search a particular scope of folders for items.

The topics in this section outline the Web Storage System's support for the WebDAV protocol.


MOVE

Use the MOVE method to move a resource to another local URL.

Example

Request

MOVE /pub2/folder1/folder2 HTTP/1.1
Destination: /pub2/folder1/folder3
Host: hostname
© 2000-2001 Microsoft Corporation. All rights reserved.


COPY

Use the COPY method to copy a resource to another local URL.

Example

Request

COPY /pub2/folder1/folder2 HTTP/1.1
Destination: /pub2/folder1/folder3
Host: hostname
© 2000-2001 Microsoft Corporation. All rights reserved.


DELETE

Use the DELETE method to delete a resource at the specified URL.

Example

Request

DELETE /pub2/folder1/folder2 HTTP/1.1
Host: hostname
Content-Length: 0
© 2000-2001 Microsoft Corporation. All rights reserved.


MKCOL

Use the MKCOL method to create a new collection (folder) at the specified URL. When invoked without a request body, it will not create members. When used with a request body, you can create members and properties on the collections or members.

Example

Request

MKCOL /pub2/folder1/folder2/ HTTP/1.1
Host: hostname
Content-Type: text/xml
Content-Length: XXX

<?xml version="1.0"?>
<g:propertyupdate xmlns:g="DAV:" >
    <g:set>
        <g:prop>
            <g:displayname>value</g:displayname>
        </g:prop>
        <g:prop>
            <f:myprop xmlns:f="urn:schemas-mydomain-tld:">Test</f:myprop>
        </g:prop>
    </g:set>
</g:propertyupdate>
© 2000-2001 Microsoft Corporation. All rights reserved.


PROPFIND

Use the PROPFIND method to retrieve properties for a resource identified by URL. Clients may submit a depth header with a value of 0, 1 or infinity. A PROPFIND without a depth header defaults to the infinity value.

Note A PROPFIND with depth infinity is not supported in the public store accessible to Messaging Application Programming Interface (MAPI) clients such as Microsoft Outlook.

Example

Request

PROPFIND /public/docs/myFile.doc HTTP/1.1
Content-Type: text/xml
Content-Length: XXX
Depth: 0
Translate: f
...

<?xml version="1.0"?>
<a:propfind xmlns:a="DAV:">
 <a:prop><a:getcontenttype/></a:prop>
 <a:prop><a:getcontentlength/></a:prop>
</a:propfind>

Response

HTTP/1.1 207 Multi-Status
Content-Type: text/xml
Content-Length: 310

<a:multistatus
  xmlns:b="urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/"
  xmlns:a="DAV:"
>
 <a:response>
   <a:href>http://server/public/test2/item1.txt</a:href>
   <a:propstat>
     <a:status>HTTP/1.1 200 OK</a:status>
       <a:prop>
        <a:getcontenttype>text/plain</a:getcontenttype>
        <a:getcontentlength b:dt="int">33</a:getcontentlength>
       </a:prop>
   </a:propstat>
 </a:response>
</a:multistatus>
© 2000-2001 Microsoft Corporation. All rights reserved.


PROPPATCH

The PROPPATCH method sets properties for the resource at the specified URL. All property names must be scoped in the XML body using namespace URI references.

Example

Request

PROPPATCH /docs/myfile.doc HTTP/1.1
Host: domain.tld
Content-Type: text/xml
Content-Length: XXX
Translate: f

<?xml version="1.0">
<d:propertyupdate xmlns:d="DAV:" xmlns:o="urn:schemas-microsoft-com:office:office">
  <d:set>
    <d:prop>
      <o:Author>Ray Zambroski</o:Author>
    </d:prop>
  </d:set>
</d:propertyupdate>

Response

HTTP/1.1 207 Multi-Status
Server: Microsoft-IIS/5.0
Date: Wed, 04 Aug 1999 21:52:58 GMT
Content-Type: text/xml
Content-Length: 310

<?xml version="1.0"?>
<a:multistatus xmlns:b="urn:schemas-microsoft-com:office:office" xmlns:a="DAV:">
  <a:response>
    <a:href>http://domain.tld/docs/myfile.doc</a:href>
    <a:propstat>
      <a:status>HTTP/1.1 200 OK</a:status>
        <a:prop>
          <b:Author/>
        </a:prop>
    </a:propstat>
  </a:response>
</a:multistatus>
© 2000-2001 Microsoft Corporation. All rights reserved.


SEARCH

Use the SEARCH method to search a scope of Web Storage System folders for resources.

Example

Request

SEARCH /vroot/folder/ HTTP/1.1
Content-Type: text/xml
Content-Length: XXX
Host: server.tld
...

<?xml version="1.0"?>
<D:searchrequest xmlns:D = "DAV:" >
   <D:sql>
   SELECT "DAV:contentclass", "DAV:displayname"
   FROM "/vroot/folder/"
   WHERE "DAV:ishidden" = false
     AND "DAV:isfolder" = false
   </D:sql>
</D:searchrequest>

Response

HTTP/1.1 207 Multi-Status
Server: Microsoft-IIS/5.0
Date: Thu, 09 Mar 2000 06:36:40 GMT
WWW-Authenticate: Negotiate XXXX
Content-Type: text/xmlAccept-Ranges: rowsTransfer-Encoding: chunked
<?xml version="1.0"?><a:multistatus xmlns:b="urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/" xmlns:a="DAV:">
 <a:response>
   <a:href>http://server.tld/vroot/folder/item2.txt</a:href>
   <a:propstat>
     <a:status>HTTP/1.1 200 OK</a:status>
     <a:prop>
         <a:contentclass>urn:content-classes:document</a:contentclass>
         <a:displayname>item2.txt</a:displayname>
      </a:prop>
   </a:propstat>
 </a:response>
 <a:response>
   <a:href>http://server.tld/vroot/folder/item1.txt</a:href>
   <a:propstat>
     <a:status>HTTP/1.1 200 OK</a:status>
     <a:prop>
        <a:contentclass>urn:content-classes:document</a:contentclass>
        <a:displayname>item1.txt</a:displayname>
     </a:prop>
   </a:propstat>
 </a:response>
</a:multistatus>
© 2000-2001 Microsoft Corporation. All rights reserved.


WebDAV Protocol Errors

The following table lists the error codes returned by the Microsoft Exchange 2000 Server WebDAV protocol service. Along with each error code or group of codes are the names of associated HTTP methods and a description of each error code.

Error Code | Method | Description
All 100 level codes | * | Informational
100 Continue [HTTP] |  | Initial part of incomplete request was accepted by server. [HTTP]
101 Switching Protocols [HTTP] |  | Server wants to switch to a newer version, or real-time protocol, to continue. Used when an Upgrade header was in the client request. [HTTP]
102 Processing [WEBDAV] | MOVE, COPY | Can be used to indicate status of ongoing processes, particularly processes that use the Depth header. This is to avoid having the client time-out with an error. [WEBDAV]
All 200 level codes | * | Success
200 OK [HTTP] | GET, HEAD, OPTIONS, LOCK, POST, DELETE | Typical successful response for these methods, in cases where no new resource is created. [HTTP]
 | SUBSCRIBE, UNSUBSCRIBE | Possible success response.
 | TRACE | Trace was reflected back to sender [HTTP]
 | PROPFIND, PROPPATCH | Possible successful response if all props were successfully returned or set. Not used in Microsoft implementations, see code 207. [WEBDAV]
201 Created [HTTP] | POST, PUT | Resource successfully created [HTTP]. If the action cannot be completed immediately, a 202 must be returned instead. [HTTP1.1]
 | MKCOL, MOVE | Collection successfully created or resource successfully moved. [WEBDAV]
 | MKREF | Reference successfully created.
 | LOCK | If you do a LOCK on a null resource, the LOCK will create the resource.
202 Accepted [HTTP] | DELETE, PUT, POST | Resource will be created or deleted but it has not yet been created or deleted [HTTP].
203 Non-authoritative Information [HTTP] | Any? | Meta-information in the header did not come from origin server. Used only when response would otherwise be 200 OK. [HTTP] Use of this response code is not required. [HTTP1.1]
204 No Content [HTTP] | POST, PUT | Standard success response when no resource was created [HTTP]. The server has fulfilled the request but does not need to return an entity-body, and might want to return updated meta information. [HTTP1.1] With PUT, the 204 response allows the server to send back an updated etag and other entity information about the resource that has been affected by the PUT operation. This allows the client to do the next PUT using the If-Match precondition to ensure that edits are not lost.
 | DELETE, UNLOCK | Standard success response. [WEBDAV]
 | COPY, MOVE | The source resource was successfully copied or moved to a pre-existing destination resource. [WEBDAV]
205 Reset Content [HTTP] |  | Server has fulfilled request and client should reset document view. Must not include an entity. [HTTP]
206 Partial Content [HTTP] | GET | Only some of the resource was returned, with Range header to indicate how much. [HTTP]
207 MultiStatus [WEBDAV] | PROPFIND, PROPPATCH, SEARCH, MKCOL | Typical successful response. [WEBDAV]
 | SUBSCRIBE, UNSUBSCRIBE | Typical successful response.
 | COPY, MOVE | If an error in executing the COPY occurs with a resource other than the request URI, then the response must be 207. 424 and 201 responses should NOT be values in 207 multistatus responses to COPY. [WEBDAV]
 | LOCK | Used with a multiresource lock request. [WEBDAV]
All 300 level codes | * | Redirection– (further action must be taken to complete request)
300 Multiple Choices [HTTP] | GET, HEAD | The requested resource corresponds to any one of a set of representations, each with its own specific location, and agent-driven negotiation information (section 12) is being provided so that the user (or user agent) can select a preferred representation and redirect its request to that location. [HTTP]
301 Moved Permanently [HTTP] | GET, HEAD | New permanent URI has been assigned to resource. [HTTP]
 | PUT | Server wishes to apply the PUT to a different URI than the one in the method.
302 Moved Temporarily [HTTP] | GET, HEAD | New temporary URI has been assigned to resource. [HTTP]
302 Found [HTTP1.1] | GET, HEAD, other | The requested resource resides temporarily under a different URI. Since the redirection might be altered on occasion, the client SHOULD continue to use the Request-URI for future requests. [HTTP1.1]
303 See Other [HTTP] | POST | Typically used to respond to a POST, because a response to a POST cannot be stored in the cache, but the response to a GET can. Client uses GET to see other. [HTTP]
304 Not Modified [HTTP] |  | If the client has performed a conditional GET request and access is allowed, but the document has not been modified, the server SHOULD respond with this status code. The response MUST NOT contain a message-body. [HTTP]
305 Use Proxy [HTTP] | Any | The requested resource MUST be accessed through the proxy given by the Location field. [HTTP1.1]
306 Unused |  | The 306 status code was used in a previous version of the specification and is no longer used; in addition, the code is reserved. [HTTP1.1]
307 Temporary Redirect [HTTP1.1] | GET, HEAD | The requested resource resides temporarily under a different URI.
All 400 level codes | * | Client Failure
400 Bad Request [HTTP] | Any | Malformed syntax, for example, empty namespace name in the XML body. [HTTP]
 | MKREF | User attempted to order a member before or after itself.
 | SUBSCRIBE | Illegal combination of headers.
 | SEARCH | No body, invalid scope, etc. The query could not be executed. The request may be malformed (for example, invalid XML). In addition, this can be used for invalid scopes and search redirections.
401 Unauthorized [HTTP] | Any | Resource requires authorization or authorization was refused [HTTP]
 | PROPPATCH | Execute a PROPPATCH on two properties, one of which requires authentication to change and the other does not. Result: The entire request will be rejected with a 401.
402 Payment Required [HTTP] | Any |
403 Forbidden [HTTP] | Any | The server understood the request but will not do it. Authorization will not help.
 | MKCOL, LOCK, PROPPATCH | Client does not have permissions to make a collection, lock the resource, or set a property. [WEBDAV] Check-out attempt: this will be returned if the resource is not versioned or if the resource is a collection.
404 Not Found [HTTP] | Any | Resource named was not found. [HTTP]
405 Method Not Allowed [HTTP] | Any | The method was not allowed for the resource named. [HTTP] The response MUST include an Allow header containing a list of valid methods for the requested resource. [HTTP1.1]
 | MKCOL | This might occur if the resource already exists and thus cannot be created. [WEBDAV]
 | MKREF | Not an ordered collection.
406 Not Acceptable [HTTP] | Any | The resource identified by the request is capable only of generating response entities that have content characteristics that are not acceptable according to the Accept headers sent in the request. The response SHOULD include an entity containing a list of available entity characteristics and location(s) from which the user or user agent can choose the one most appropriate. [HTTP1.1]
 | HEAD | The response need not include an entity as above.
 | SUBSCRIBE | SUBSCRIBE request had an Accept header that the server could not satisfy.
407 Proxy Authentication Required [HTTP] | Any | This code is similar to 401 (Unauthorized), but it indicates that the client MUST first authenticate itself with the proxy. [HTTP1.1]
408 Request Timeout [HTTP] | Any | The client did not produce a request within the time that the server was prepared to wait. [HTTP1.1]
409 Conflict [HTTP] | MKCOL | A collection cannot be created until intermediate collections have been created. [WEBDAV]
 | PROPPATCH | The client has provided a value whose semantics are not appropriate for the property, for example, trying to set a read-only property. [WEBDAV]
 | PUT | Cannot PUT a resource if all ancestors do not already exist. [WEBDAV] If versioning is being used and the entity being PUT includes changes to a resource that conflict with those made by an earlier (third-party) request, the server might use the 409 response code to indicate that it can't complete the request. [HTTP1.1]
 | MKREF | Member named for ordering does not exist in the collection.
 | SUBSCRIBE | Invalid or unsupported notification type.
410 Gone [HTTP] | GET | The requested resource is no longer available on the server and no forwarding address is known. This condition is considered permanent. [HTTP1.1]
411 Length Required [HTTP] | Any | The server refuses to accept the request without a defined Content-Length. [HTTP1.1]
412 Precondition Failed [HTTP] | Any | The precondition given in one or more of the Request header fields evaluated to false when it was tested on the server. [HTTP1.1]
 | COPY, MOVE | The server was unable to maintain the live-ness of the properties listed in the property behavior XML element, or the overwrite header is F and the state of the destination resource is non-null. [WEBDAV]
 | LOCK | The lock token could not be enforced or the server could not satisfy the request in the lockinfo XML element.
 | SUBSCRIBE, UNSUBSCRIBE | The subscription-ID(s) in the header did not match the resource named. This could be because the subscription-ID does not exist any more.
413 Request Entity Too Large [HTTP] | Any | The server refuses to process a request because the request entity is larger than what the server is willing or able to process. [HTTP1.1]
414 Request URI Too Large [HTTP] | Any | The server refuses to service the request because the Request-URI is longer than what the server is willing to interpret. [HTTP1.1]
415 Unsupported Media Type [HTTP] | Any | The server refuses to service the request because the entity of the request is in a format that is not supported by the requested resource for the requested method.
 | MKCOL | The server does not support the request type of the body. [WEBDAV]
416 Requested Range Not Satisfiable [HTTP1.1] |  | A server SHOULD return a response with this status code if a request included a Range request-header field (section 14.35), if none of the range-specifier values in this field overlap with the current extent of the selected resource, and if the request did not include an If-Range request-header field. [HTTP1.1]
417 Expectation Failed [HTTP1.1] |  | The expectation given in an Expect request-header field (see section 14.20) could not be met by this server or, if the server is a proxy, the server has unambiguous evidence that the next-hop server could not meet the request. [HTTP1.1]
422 Unprocessable Entity [WEBDAV] | MKCOL | The server understands the content type of the request entity, but was unable to process the instructions that it contains. [WEBDAV] For example, the MKCOL has a request body that is not understood or is incomplete, even if in XML, which is generally accepted in this situation.
 | SEARCH | Valid XML body in SEARCH, but unsupported or unimplemented query operator.
 | LOCK | Non-zero depth was specified for a check-out lock, or the Depth header was omitted.
423 Locked [WEBDAV] | PROPPATCH, DELETE, MOVE | Cannot set properties on, delete, move, or lock a locked resource without the lock token. [WEBDAV]
 | LOCK | Already locked (need lock token). [WEBDAV] The user tries to create a transaction within a transaction [TRANS].
 | COPY | The destination resource was locked. [WEBDAV]
424 Method Failure [WEBDAV] | PROPPATCH | The method was not executed on a resource because some part of the method's execution failed and the whole method was aborted. [WEBDAV]
 | UNLOCK | One of the methods in the transaction failed, therefore the entire transaction failed.
425 Insufficient Space on Resource | SEARCH | The query produced more results than the server was willing to transmit. Partial results have been transmitted.
All 500 Level Codes | * | Server Failure
500 Internal Server Error [HTTP] |  | The server encountered an unexpected condition that prevented it from fulfilling the request. [HTTP1.1]
501 Not Implemented [HTTP] | Any | The server does not support the functionality that is required to fulfill the request. This is the appropriate response when the server does not recognize the request method and is not capable of supporting it for any resource. [HTTP1.1]. Contrast with 405.
 | PUT | Error when a server receives a Content-* header it does not understand in a PUT operation.
 | SUBSCRIBE | Server does not support the notification method (UDP callback or delivery-control header).
502 Bad Gateway [HTTP] |  | The server, while acting as a gateway or proxy, received an invalid response from the upstream server that it accessed in attempting to fulfill the request. [HTTP1.1]
 | COPY, MOVE | The destination could be on another server and the destination server refuses to accept the resource. [WEBDAV]
503 Service Unavailable [HTTP] |  | The server is currently unable to handle the request due to temporary overloading or to maintenance of the server. The implication is that this is a temporary condition that will be alleviated after a delay. [HTTP1.1]
504 Gateway Timeout |  | The server, while acting as a gateway or proxy, did not receive a timely response from the upstream server specified by the URI (for example, HTTP, FTP, LDAP) or some other auxiliary server (for example, DNS) that it needed to access to complete the request. [HTTP1.1]
505 HTTP Version not supported | Any | The server does not support, or refuses to support, the HTTP protocol version that was used in the request message. [HTTP1.1]
507 Insufficient Storage | PROPPATCH, MKCOL | The resource does not have enough space to set the properties or make the collection. [WEBDAV]
 | COPY | The destination resource does not have sufficient space. [WEBDAV]
 | SEARCH | The query produced more results than the server was willing to transmit. Partial results have been transmitted. The server MUST send a body that matches the body for code 207, except that there MAY exist resources that matched the search criteria for which no corresponding response exists in the reply.

References

WebDAV | Goland et al, HTTP Extensions for Distributed Authoring -- WEBDAV, RFC 2518.
HTTP | T. Berners-Lee et al, Hypertext Transfer Protocol -- HTTP/1.0, RFC 1945.
HTTP 1.1 | Fielding et al, HyperText Transfer Protocol -- HTTP/1.1, RFC 2616.


Exchange 2000 Instant Messaging Service

The following sections contain reference information to use when developing Instant Messages for Microsoft® Exchange 2000 Server.

COM Classes

Enumerations

Interfaces

DISPID Values

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


COM Classes

The topics in this section describe the Instant Messaging Service (IM) Component Object Model (COM) classes.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


MSIMContactView CoClass

Defines an object used to access contact list views.

CLSID
B06EDBC7-287D-405C-A899-9C7F8358EF26
ProgID
MSExchangeIM.MSIMContactView
Type Library
MSIM Control 1.0 Type Library
Inproc Server
MSIMCntl.dll
Threading Model
Single

Implemented Interfaces

IMSIMContactView

DMSIMContactViewEvents

© 2000-2001 Microsoft Corporation. All rights reserved.


MSIMHost CoClass

Defines an object used for accessing Microsoft® Exchange Instant Messaging Service (IM) services and services used by IM solutions.

CLSID
0E16DE3E-3470-4588-9113-903713375D4F
ProgID
MSExchangeIM.MSIMHost
Type Library
Microsoft Exchange Instant Messaging Client 1.0 Type Library
Threading Model
Single

Implemented Interfaces

IMSIMHost

DMSIMHostEvents

© 2000-2001 Microsoft Corporation. All rights reserved.


MSIMHostOption CoClass

The Property Page class for MSIMHost.exe options.

CLSID
F71FB4C1-4539-4022-8EAD-8C2D473770C2
ProgID
MSExchangeIM.MSIMHostOption
Type Library
Microsoft Exchange Instant Messaging Client 1.0 Type Library
Threading Model
Single

Implemented Interfaces

IPropertyPage

© 2000-2001 Microsoft Corporation. All rights reserved.


MSIMHostProfiles CoClass

The Property Page that allows the user to set their default Instant Messaging (IM) address for use with MSIMHost.

CLSID
4AE5D919-D316-470F-A073-1F569B4BD3EA
ProgID
MSExchangeIM.MSIMHostProfiles
Type Library
Microsoft Exchange Instant Messaging Client 1.0 Type Library
Threading Model
Single

Implemented Interfaces

IPropertyPage

© 2000-2001 Microsoft Corporation. All rights reserved.


MSIMMessageView CoClass

Defines an object used to manage a message window.

CLSID
528B6917-4DED-43F1-B56C-35A1519129CA
ProgID
MSExchangeIM.MSIMMessageView
Type Library
MSIM Control 1.0 Type Library
Inproc Server
MSIMCntl.dll
Threading Model
Single

Implemented Interfaces

IMSIMMessageView

DMSIMMessageViewEvents

© 2000-2001 Microsoft Corporation. All rights reserved.


Enumerations

The topics in this section describe the Instant Messaging Service (IM) Enumerations.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


IM_INVITE_FLAGS_TYPE Enum

Name | Value | Description
IM_INVITE_TYPE_REQUEST_LAUNCH | 0x00000001 | Requests that the invited application be started.
IM_INVITE_TYPE_REQUEST_IP | 0x00000004 | Requests that the remote client send its IP address.
IM_INVITE_TYPE_PROVIDE_IP | 0x00000008 | Requests that the local client provide its IP address.


IM_MSG_TYPE Enum

Name | Value | Description
IM_MSG_TYPE_NO_RESULT | 0 | Do not generate OnSendResult notification at local client on receipt.
IM_MSG_TYPE_ERRORS_ONLY | 1 | Do not generate OnSendResult notification at local client on receipt unless an error occurred.
IM_MSG_TYPE_ALL_RESULTS | 2 | Generate OnSendResult notification at local client on receipt.


IM_RESULTS Enum

Name | Value | Description
IM_E_CONNECT | 0x81000301 | The Winsock layer could not establish a connection.
IM_E_INVALID_SERVER_NAME | 0x81000302 | Reserved for future use.
IM_E_INVALID_PASSWORD | 0x81000303 | The password provided by the user is invalid.
IM_E_ALREADY_LOGGED_ON | 0x81000304 | The local client is already logged on to a server.
IM_E_SERVER_VERSION | 0x81000305 | The server version is incompatible with the local client version.
IM_E_LOGON_TIMEOUT | 0x81000306 | The logon attempt timed out after 15 seconds.
IM_E_LIST_FULL | 0x81000307 | There are too many contacts in a list.
IM_E_AI_REJECT | 0x81000308 | A contact has rejected a Microsoft® NetMeeting® invitation.
IM_E_AI_REJECT_NOT_INST | 0x81000309 | A remote client has rejected a NetMeeting 3.01 invitation because it does not exist on the remote user’s computer.
IM_E_USER_NOT_FOUND | 0x8100030A | The server cannot find the requested user. This could be because the user does not exist, the username is invalid, or adding a user failed on the server side.
IM_E_ALREADY_IN_LIST | 0x8100030B | The local client has attempted to add a user to a list, but that username already exists in the contact list.
IM_E_DISCONNECTED | 0x8100030C | The local client has logged off.
IM_E_UNEXPECTED | 0x8100030D | The server has returned an unexpected error code.
IM_E_SERVER_TOO_BUSY | 0x8100030E | The server is either not processing requests or not accepting new connections.
IM_E_INVALID_AUTH_PACKAGES | 0x8100030F | No common authentication mechanism has been negotiated, or it has not been initialized properly.
IM_E_NEWER_CLIENT_AVAILABLE | 0x81000310 | While logging on, the server returns a message that a newer client installation is available.
IM_E_AI_TIMEOUT | 0x81000311 | A remote client has not responded to an application invitation, and the local client has timed out the invitation request.
IM_E_CANCEL | 0x81000312 | The local client has cancelled a logon attempt.
IM_E_TOO_MANY_MATCHES | 0x81000313 | Reserved for future use.
IM_E_SERVER_UNAVAILABLE | 0x81000314 | The server was contacted, but was unavailable for unspecified reasons.
IM_E_LOGON_UI_ACTIVE | 0x81000315 | Reserved for future use.
IM_E_OPTION_UI_ACTIVE | 0x81000316 | Reserved for future use.
IM_E_CONTACT_UI_ACTIVE | 0x81000317 | Reserved for future use.
IM_E_LOGGED_ON | 0x81000319 | The client was logged on. This is returned in cases where the client must be offline.
IM_E_CONNECT_PROXY | 0x8100031A | Reserved for future use.
IM_E_PROXY_AUTH | 0x8100031B | Reserved for future use.
IM_E_PROXY_AUTH_TYPE | 0x8100031C | Reserved for future use.
IM_E_INVALID_PROXY_NAME | 0x8100031D | Reserved for future use.
IM_E_NOT_PRIMARY_SERVICE | 0x81000320 | Reserved for future use.
IM_E_TOO_MANY_SESSIONS | 0x81000321 | Reserved for future use.
IM_E_TOO_MANY_MESSAGES | 0x81000322 | Reserved for future use.
IM_E_REMOTE_LOGIN | 0x81000323 | Reserved for future use.
IM_E_INVALID_FRIENDLY_NAME | 0x81000324 | Reserved for future use.
IM_E_SESSION_FULL | 0x81000325 | Reserved for future use.
IM_E_NOT_ALLOWING_NEW_USERS | 0x81000326 | Reserved for future use.
IM_E_INVALID_DOMAIN | 0x81000327 | Reserved for future use.
IM_E_TCP_ERROR | 0x81000328 | Reserved for future use.
IM_E_SESSION_TIMEOUT | 0x81000329 | Reserved for future use.
IM_E_MULTIPOINT_SESSION_BEGIN_TIMEOUT | 0x8100032a | Reserved for future use.
IM_E_MULTIPOINT_SESSION_END_TIMEOUT | 0x8100032b | Reserved for future use.
IM_E_REVERSE_LIST_FULL | 0x8100032c | Reserved for future use.
IM_E_SERVER_ERROR | 0x8100032d | The server has encountered an error.
IM_E_SYSTEM_CONFIG | 0x8100032e | A required library was not found.
IM_E_NO_DIRECTORY | 0x8100032f | Reserved for future use.
IM_E_USER_CANCELED_LOGON | 0x81000350 | The user canceled the logon dialog.
IM_S_LOGGED_ON | 0x01000319 | The user is already logged on.
IM_S_ALREADY_IN_THE_MODE | 0x01000301 | A modal setting was already at the requested setting.


IM_STATE Enum

Name | Value | Description
IM_STATE_UNKNOWN | 0x0000 | The state of the local or remote client is unknown.
IM_STATE_OFFLINE | 0x0001 | The local or remote client is not connected to a server.
IM_STATE_ONLINE | 0x0002 | The local or remote client is connected to a server.
IM_STATE_INVISIBLE | 0x0006 | The local or remote client is connected to a server but invisible to other users.
IM_STATE_BUSY | 0x000A | The local or remote client is connected to a server and in a user-selected state of Busy.
IM_STATE_BE_RIGHT_BACK | 0x000E | The local or remote client is in a user-selected state of Be Right Back.
IM_STATE_IDLE | 0x0012 | The local or remote client has not detected mouse or keyboard input on the computer for a determined time. The user is most likely away from the computer. Whether to transmit the idle state and the idle time threshold are based on the screen saver.
IM_STATE_AWAY | 0x0022 | The local or remote client user has stepped away from the computer (a user-selected state).
IM_STATE_ON_THE_PHONE | 0x0032 | The local or remote client user is in a user-selected state of On The Phone.
IM_STATE_OUT_TO_LUNCH | 0x0042 | The local or remote client user is in a user-selected state of Out To Lunch.
IM_STATE_LOCAL_FINDING_SERVER | 0x0100 | The local client is attempting to find the server.
IM_STATE_LOCAL_CONNECTING_TO_SERVER | 0x0200 | The local client is connecting to the server.
IM_STATE_LOCAL_SYNCHRONIZING_WITH_SERVER | 0x0300 | The local client is synchronizing with the server.
IM_STATE_LOCAL_DISCONNECTING_FROM_SERVER | 0x0400 | The local client is disconnecting from the server.


IM_SSTATE Enum

Name | Value | Description
IM_SSTATE_DISCONNECTED | 0 | The local client's session is not connected to the server.
IM_SSTATE_CONNECTING | 1 | The local client is in the process of connecting the session.
IM_SSTATE_CONNECTED | 2 | The local client's session is connected to the server.
IM_SSTATE_DISCONNECTING | 3 | The local client is in the process of disconnecting the session.
IM_SSTATE_ERROR | 4 | Reserved for future use.


MSIM_LIST_TYPE Enum

Name | Value | Description
MSIM_LIST_CONTACT | 0x00000001 | The list of Instant Messaging contacts whose status the user is tracking.
MSIM_LIST_ALLOW | 0x00000002 | The list of Instant Messaging contacts that are explicitly allowed to track the user’s status.
MSIM_LIST_BLOCK | 0x00000004 | The list of Instant Messaging contacts that are explicitly blocked from tracking the user’s status and sending the user messages.
MSIM_LIST_REVERSE | 0x00000008 | The list of Instant Messaging contacts that are currently tracking the user’s status.
MSIM_LIST_NOREF | 0x00000010 | Indicates that the MSIMHost Executable will not hold a reference to the list. It is up to the client application to hold reference to this list. When all references are released, this list is removed from memory. IIMService::RemoveList does not need to be called for this list type.
MSIM_LIST_SAVE | 0x00000020 | For future use.
MSIM_LIST_SYSTEM | 0x00000080 | Indicates that a list is a default list.


MSIM_MSG_UI Enum

Name | Value | Description
MSIM_MSG_UI_SESSION | 0 | Indicates that an IM session was requested.
MSIM_MSG_UI_NETMEETING | 1 | Indicates that a NetMeeting session was requested.


MSIM_PROVIDER Enum

Name | Value | Description
MSIM_PROVIDER_ANY | 0 | Attempts to connect to Microsoft® Exchange 2000 Instant Messaging Service .
MSIM_PROVIDER_EXCHANGE_HOST | 1 | Sets the provider as Microsoft® Exchange 2000 Instant Messaging Service.
MSIM_PROVIDER_NONE | 0xFFFF | No provider has been set.


MSIMWND_SIZE_TYPE Enum

Name | Value | Description
MSIMWND_SIZE_MAXHIDE | 1 | Indicates that the window was hidden.
MSIMWND_SIZE_MAXIMIZED | 2 | Indicates that the window was maximized.
MSIMWND_SIZE_MAXSHOW | 3 | Indicates that the window was displayed.
MSIMWND_SIZE_MINIMIZED | 4 | Indicates that the window was minimized.
MSIMWND_SIZE_RESTORED | 5 | Indicates that the window was restored.


MSIMWND_STYLES Enum

Name | Value | Description
MSIMWND_WS_OVERLAPPED | 0 | Creates a window with a caption and border with full window functionality.
MSIMWND_WS_TOOL | 1 | Creates a tool window.
MSIMWND_WS_POPUP | 2 | Creates a pop-up window.
MSIMWND_WS_DIALOG | 3 | Creates a dialog box window.
MSIMWND_WS_SIZEBOX | 4 | Creates a window with a size box.


Interfaces

The topics in this section describe the Instant Messaging Service (IM) Interfaces.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


DIMServiceEvents Interface

The DIMServiceEvents interface handles notifications that are generated or received by an IMService object.

IID
4153D194-2A21-4aca-8DCB-C09BEA9F7E51
Extends
IDispatch

Member Summary

Methods

Name | Description
OnAppShutdown | Indicates that a Microsoft® Exchange 2000 Instant Messaging Service (IM) host application is shutting down.
OnContactStateChanged | Indicates that the state of a contact has changed.
OnFindResult | Indicates that results from a FindContact request to the server have been returned to the local client. A single FindContact request can generate multiple OnFindResult notifications.
OnFriendlyNameChangeResult | Indicates that the friendly name of the indicated contact has changed.
OnInviteContact | Indicates that the local client has received an answer from a contact in response to an invitation to join a new or existing IM session.
OnListAddResult | Indicates that a contact has been added to one of the local client’s lists, or that an addition was attempted.
OnListRemoveResult | Indicates that a contact has been removed from one of the local client’s lists, or that a removal was attempted.
OnLocalFriendlyNameChangeResult | Indicates that the local user’s friendly name has been changed.
OnLocalStateChangeResult | Indicates that the local client’s state has been changed, or that a state change was attempted.
OnLogoff | Indicates that the local client has logged off from all services.
OnLogonResult | Indicates that the local client has attempted to connect to the server.
OnNetMeetingInviteAccepted | Indicates that an invitation to join Microsoft® NetMeeting® sent by the local client has been accepted by a remote client.
OnNetMeetingInviteCancelled | Indicates that an invitation to join NetMeeting sent by the local client has been cancelled by a remote client.
OnNetMeetingInviteReceived | Indicates that an invitation from a remote client to join NetMeeting has been received by the local client.
OnNewSessionMember | Indicates that a new contact has joined an IM session.
OnNewSessionRequest | Indicates that the local client has received a request to start a new IM session.
OnSendResult | Indicates the status of the message the local client sent to a remote client.
OnSessionMemberLeave | Indicates that a contact has left an IM session.
OnSessionStateChange | Indicates that the state of an IM session on the local client has changed.
OnTextReceived | Indicates that text has been received from a contact connected to the server, or from the server itself.


OnAppShutdown Method

The OnAppShutdown method indicates that an IM host application is shutting down.

[Visual Basic,VBScript]
Event OnAppShutdown()
[C++]
void OnAppShutdown();
[IDL]
void OnAppShutdown();

Remarks

When a client application receives this event, it must clean up and release all references to interfaces in the IM client components.


OnContactStateChanged Method

The OnContactStateChanged method indicates that the state of a contact has changed.

[Visual Basic,VBScript]
Event OnContactStateChanged(
   pContact As Object,
   lPrevState As Long,
   bstrDescription As String,
   pvarData As Variant
)
[C++]
void OnContactStateChanged(
   IDispatch* pContact,
   long lPrevState,
   BSTR bstrDescription,
   VARIANT* pvarData
);
[IDL]
void OnContactStateChanged(
   [in] IDispatch* pContact,
   [in] long lPrevState,
   [in] BSTR bstrDescription,
   [in] VARIANT *pvarData
);
lPrevState
A member of the IM_STATE enumeration specifying the previous state of the Contact object.
bstrDescription
A description of the previous state generated by the host.
pvarData
Reserved for future use.

Remarks

This notification does not provide information on the new state of the Contact object. To determine the new state of the Contact object, use the IIMContact.State property.

OnContactStateChanged is only received when contacts in the local user’s Contact list change their states. This notification is not received if contacts in the Allow, Block, or Reverse lists change their states.


OnFindResult Method

The OnFindResult method indicates that results from a FindContact request to the server have been returned to the local client. A single FindContact request can generate multiple OnFindResult notifications.

[Visual Basic,VBScript]
Event OnFindResult(
   lResult As Long,
   lCookie As Long,
   lFindIndex As Long,
   lTotalResults As Long,
   bstrAlias As String,
   bstrFirstName As String,
   bstrLastName As String,
   bstrCity As String,
   bstrState As String,
   bstrCountry As String
)
[C++]
void OnFindResult(
   long lResult,
   long lCookie,
   long lFindIndex,
   long lTotalResults,
   BSTR bstrAlias,
   BSTR bstrFirstName,
   BSTR bstrLastName,
   BSTR bstrCity,
   BSTR bstrState,
   BSTR bstrCountry
);
[IDL]
void OnFindResult(
   [in] long lResult,
   [in] long lCookie,
   [in] long lFindIndex,
   [in] long lTotalResults,
   [in] BSTR bstrAlias,
   [in] BSTR bstrFirstName,
   [in] BSTR bstrLastName,
   [in] BSTR bstrCity,
   [in] BSTR bstrState,
   [in] BSTR bstrCountry
);
lResult
The error value returned by the server.
lCookie
The returned cookie, which matches the lCookie value of the original IIMService::FindContact method invocation that produced this notification.
lFindIndex
The index from the list of total results for this particular notification. This is a one-based index; if lFindIndex is zero, no contacts were found.
lTotalResults
The number of notifications sent in response to the IIMService::FindContact method. The number of notifications is equal to the total number of contacts found as long as the total did not exceed a server-determined limit. If the total did exceed a server-determined limit, lResult returns IM_E_TOO_MANY_MATCHES. If lTotalResults is zero, no contacts were found.
bstrAlias
The IM address of a contact who matched the parameters given in the original IIMService::FindContact method. If bstrAlias is NULL or an empty string, no contacts were found.
bstrFirstName
The first name of a contact who matched the parameters given in the original IIMService::FindContact method. If bstrFirstName is NULL or an empty string, no contacts were found.
bstrLastName
The last name of a contact who matched the parameters given in the original IIMService::FindContact method. If bstrLastName is NULL or an empty string, no contacts were found.
bstrCity
Reserved for future use.
bstrState
Reserved for future use.
bstrCountry
Reserved for future use.

Remarks

If there were no errors, and multiple matches were found, each contact found generates its own OnFindResult notification. The number of results is indicated by lTotalResults, which has the same value in each notification. If an error occurs, the error is packaged as the lResult value of a single OnFindResult notification, and the remaining parameters are NULL.


OnFriendlyNameChangeResult Method

The OnFriendlyNameChangeResult method indicates that the friendly name of the indicated contact has changed.

[Visual Basic,VBScript]
Event OnFriendlyNameChangeResult(
   lResult As Long,
   pContact As Object,
   bstrPrevFriendlyName As String
)
[C++]
void OnFriendlyNameChangeResult(
   long lResult,
   IDispatch* pContact,
   BSTR bstrPrevFriendlyName
);
[IDL]
void OnFriendlyNameChangeResult(
   [in] long lResult,
   [in] IDispatch* pContact,
   [in] BSTR bstrPrevFriendlyName
);
lResult
The error value returned by the server.
bstrPrevFriendlyName
The contact’s previous friendly name.

Remarks

This notification fires when a local client receives an Instant Message from, or gets a state update about, a remote client that already exists as a Contact object in one of the local client lists. The friendly name sent with the message or state protocol message is compared to the friendly name previously stored for that contact object. If there is a difference, the OnContactFriendlyNameChangeResult notification is fired locally.


OnInviteContact Method

The OnInviteContact method indicates that the local client has received an answer from a contact in response to an invitation to join a new or existing IM session.

[Visual Basic,VBScript]
Event OnInviteContact(
   lResult As Long,
   pContact As Object,
   pIMSession As Object
)
[C++]
void OnInviteContact(
   long lResult,
   IDispatch* pContact,
   IDispatch* pIMSession
);
[IDL]
void OnInviteContact(
   [in] long lResult,
   [in] IDispatch* pContact,
   [in] IDispatch* pIMSession
);
lResult
The error code that gives the result of the invite request.


OnListAddResult Method

The OnListAddResult method indicates that a contact has been added to one of the local client’s lists, or that an addition was attempted.

[Visual Basic,VBScript]
Event OnListAddResult(
   lResult As Long,
   pList As Object,
   pContact As Object
)
[C++]
void OnListAddResult(
   long lResult,
   IDispatch* pList,
   IDispatch* pContact
);
[IDL]
void OnListAddResult(
   long lResult,
   IDispatch* pList,
   IDispatch* pContact
);
lResult
The return code that gives the result of the add request.

Remarks

This notification is received in response to the IIMContacts::Add method, and is potentially the first indication that a newly created Contact object is valid.

If IIMContacts::Add does not return S_OK, no notification is received. For instance, attempting to add a contact to the Reverse list is blocked by the IIMContacts::Add method, which returns E_FAIL and generates no notification.

An lResult value of IM_E_ALREADY_IN_LIST is received in response to adding a contact that is already in a list. There is no initial check of client-side lists.


OnListRemoveResult Method

The OnListRemoveResult method indicates that a contact has been removed from one of the local client’s lists, or that a removal was attempted.

[Visual Basic,VBScript]
Event OnListRemoveResult(
   lResult As Long,
   pList As Object,
   pContact As Object
)
[C++]
void OnListRemoveResult(
   long lResult,
   IDispatch* pList,
   IDispatch* pContact
);
[IDL]
void OnListRemoveResult(
   [in] long lResult,
   [in] IDispatch* pList,
   [in] IDispatch* pContact
);
lResult
The return code that gives the result of the remove request.

Remarks

This notification is returned in response to the IIMContacts::Remove method. OnListRemoveResult will not fire unless IIMContacts::Remove returns a result of S_OK.


OnLocalFriendlyNameChangeResult Method

The OnLocalFriendlyNameChangeResult method indicates that the local user’s friendly name has been changed.

[Visual Basic,VBScript]
Event OnLocalFriendlyNameChangeResult(
   lResult As Long,
   bstrPrevFriendlyName As String
)
[C++]
void OnLocalFriendlyNameChangeResult(
   long lResult,
   BSTR bstrPrevFriendlyName
);
[IDL]
void OnLocalFriendlyNameChangeResult(
   [in] long lResult,
   [in] BSTR bstrPrevFriendlyName
);
lResult
The return code that gives the result of the name change request.
bstrPrevFriendlyName
A string containing the local user’s previous friendly name.


OnLocalStateChangeResult Method

The OnLocalStateChangeResult method indicates that the local client’s state has been changed, or that a state change was attempted.

[Visual Basic,VBScript]
Event OnLocalStateChangeResult(
   lResult As Long,
   lLocalState As Long,
   bstrDescription As String,
   pvarData As Variant
)
[C++]
void OnLocalStateChangeResult(
   long lResult,
   long lLocalState,
   BSTR bstrDescription,
   VARIANT* pvarData
);
[IDL]
void OnLocalStateChangeResult(
   [in] long lResult,
   [in] long lLocalState,
   [in] BSTR bstrDescription,
   [in] VARIANT *pvarData
);
lResult
The code that gives the result of the state change request.
lLocalState
A member of the IM_STATE enumeration specifying the new state of the local contact.
bstrDescription
A description of the state generated by the host.
pvarData
Reserved for future use.

Remarks

This notification is received upon successfully invoking the IIMService::SetLocalState method, or through various API or user-driven actions that change the local state, such as logging on. If either the API or the user sets the local client state to the previous state value, no notification is received. Upon logging on, you should handle this notification to verify that the local client is IM_STATE_ONLINE. The fact that lResult returns S_OK for the DIMServiceEvents::OnLogonResult notification does not guarantee that the local client is successfully online.

Each change to a local client transitional state (such as IM_STATE_LOCAL_FINDING_SERVER during a logon action) generates another OnLocalStateChangeResult notification.


OnLogoff Method

The OnLogoff method indicates that the local client has logged off from all services.

[Visual Basic,VBScript]
Event OnLogoff(lResult As Long)
[C++]
void OnLogoff(long lResult);
[IDL]
void OnLogoff([in] long lResult);
lResult
The code that gives the result of the request.

Remarks

This notification is used to verify that the local client is logged off from all services. Logging off through either the user interface or the IIMService::Logoff method generates this notification.

This event must fire before the IIMService::Logon method is called to log a user back on to the IM server.


OnLogonResult Method

The OnLogonResult method indicates that the local client has attempted to connect to the server.

[Visual Basic,VBScript]
Event OnLogonResult(lResult As Long)
[C++]
void OnLogonResult(long lResult);
[IDL]
void OnLogonResult([in] long lResult);

Remarks

This notification is returned for both successful and unsuccessful attempts by either the IIMService::Logon method or a contact logon action through the contact interface. Because this notification does not necessarily imply that the local client is ready for other API calls, wait for the DIMServiceEvents::OnLocalStateChangeResult notification to return IM_STATE_ONLINE.


OnNetMeetingInviteAccepted Method

The OnNetMeetingInviteAccepted method indicates that an invitation to join Microsoft® NetMeeting® sent by the local client has been accepted by a remote client.

[Visual Basic,VBScript]
Event OnNetMeetingInviteAccepted(
   pIMSession As Object,
   pContact As Object,
   lInviteCookie As Long,
   lInviteType As Long,
   bstrIPAddress As String,
   pvfEnableDefault As Variant
)
[C++]
void OnNetMeetingInviteAccepted(
   IDispatch* pIMSession,
   IDispatch* pContact,
   long lInviteCookie,
   long lInviteType,
   BSTR bstrIPAddress,
   VARIANT* pvfEnableDefault
);
[IDL]
void OnNetMeetingInviteAccepted(
   [in] IDispatch* pIMSession,
   [in] IDispatch* pContact,
   [in] long lInviteCookie,
   [in] long lInviteType,
   [in] BSTR bstrIPAddress,
   [in, out] VARIANT* pvfEnableDefault
);
lInviteCookie
A numeric identifier used to correlate matching send and receive events. In this case, lInviteCookie should match the value returned by plSendCookie upon the original IIMService::SendNetMeetingInvite method invocation. The lInviteCookie value should also remain the same throughout both the remote client’s DIMServiceEvents::OnNetMeetingInviteReceived notification and the remote client’s IIMService::SendNetMeetingAccept method.
lInviteType
A member of the IM_INVITE_FLAGS_TYPE enumeration used to request and send IP address information.
bstrIPAddress
A string representation of the IP address of the remote client that accepted the invitation. This is generated automatically at the remote client.
pvfEnableDefault
A flag that indicates whether the default action will occur. If pvfEnableDefault is not set or is set to True, the default action will occur. If pvfEnableDefault is set to False, an alternative action defined by the application will occur.


OnNetMeetingInviteCancelled Method

The OnNetMeetingInviteCancelled method indicates that an invitation to join NetMeeting sent by the local client has been cancelled by a remote client.

[Visual Basic,VBScript]
Event OnNetMeetingInviteCancelled(
   pIMSession As Object,
   pContact As Object,
   lInviteCookie As Long,
   hrReason As Long,
   pvfEnableDefault As Variant
)
[C++]
void OnNetMeetingInviteCancelled(
   IDispatch* pIMSession,
   IDispatch* pContact,
   long lInviteCookie,
   long hrReason,
   VARIANT* pvfEnableDefault
);
[IDL]
void OnNetMeetingInviteCancelled(
   [in] IDispatch* pIMSession,
   [in] IDispatch* pContact,
   [in] long lInviteCookie,
   [in] long hrReason,
   [in, out] VARIANT* pvfEnableDefault
);
lInviteCookie
A numerical identifier that correlates application invitations to the corresponding DIMServiceEvents::OnNetMeetingInviteReceived notifications.
hrReason
A constant that specifies why the application invitation was rejected.
pvfEnableDefault
A flag that indicates whether the default action will occur. If pvfEnableDefault is not set or is set to True, the default action will occur. If pvfEnableDefault is set to False, an alternative action defined by the application will occur.


OnNetMeetingInviteReceived Method

The OnNetMeetingInviteReceived method indicates that an invitation from a remote client to join NetMeeting has been received by the local client.

[Visual Basic,VBScript]
Event OnNetMeetingInviteReceived(
   pIMSession As Object,
   pContact As Object,
   lInviteCookie As Long,
   pvfEnableDefault As Variant
)
[C++]
void OnNetMeetingInviteReceived(
   IDispatch* pIMSession
   IDispatch* pContact,
   long lInviteCookie,
   VARIANT* pvfEnableDefault
);
[IDL]
void OnNetMeetingInviteReceived(
   [in] IDispatch* pIMSession
   [in] IDispatch* pContact,
   [in] long lInviteCookie,
   [in, out] VARIANT* pvfEnableDefault
);
lInviteCookie
A numerical identifier that correlates application invitations to the corresponding DIMServiceEvents::OnNetMeetingInviteAccepted or DIMServiceEvents::OnNetMeetingInviteCancelled notifications.
pvfEnableDefault
A flag that indicates whether the default action will occur. If pvfEnableDefault is not set or is set to True, the default action will occur. If pvfEnableDefault is set to False, an alternative action defined by the application will occur.


OnNewSessionMember Method

The OnNewSessionMember method indicates that a new contact has joined an IM session.

[Visual Basic,VBScript]
Event OnNewSessionMember(
   pContact As Object,
   pIMSession As Object
)
[C++]
void OnNewSessionMember(
   IDispatch* pContact,
   IDispatch* pIMSession
);
[IDL]
void OnNewSessionMember(
   [in] IDispatch* pContact,
   [in] IDispatch* pIMSession
);


OnNewSessionRequest Method

The OnNewSessionRequest method indicates that the local client has received a request to start a new IM session.

[Visual Basic,VBScript]
Event OnNewSessionRequest(
   pContact As Object,
   pIMSession As Object,
   pfHandled As Variant
)
[C++]
void OnNewSessionRequest(
   IDispatch* pContact,
   IDispatch* pIMSession,
   VARIANT* pfHandled
);
[IDL]
void OnNewSessionRequest(
   [in] IDispatch* pContact,
   [in] IDispatch* pIMSession,
   [in, out] VARIANT* pfHandled
);
pfHandled
If set to True, pfHandled indicates that a listening application has handled this notification and that all other applications should ignore this notification.

Remarks

All new IM sessions are accepted without user prompt. If a user does not want to accept sessions from a particular contact, the user needs to change the privacy settings for the Block and Allow lists in the local client.


OnSendResult Method

The OnSendResult method indicates the status of the message that the local client sent to a remote client.

[Visual Basic,VBScript]
Event OnSendResult(
   lResult As Long,
   lCookie As Long
)
[C++]
void OnSendResult(
   long lResult,
   long lCookie
);
[IDL]
void OnSendResult(
   [in] long lResult,
   [in] long lCookie
);
lResult
Code sent back by the server in response to an attempt to deliver the originating Instant Message.
lCookie
The cookie generated by the SendText method.

Remarks

OnSendResult fires when you set the MsgType parameter in IIMContact::SendText or IIMSession::SendText to ALL_RESULTS or ERRORS_ONLY, and the message is an error.


OnSessionMemberLeave Method

The OnSessionMemberLeave method indicates that a contact has left an IM session.

[Visual Basic,VBScript]
Event OnSessionMemberLeave(
   pContact As Object,
   pIMSession As Object
)
[C++]
void OnSessionMemberLeave(
   IDispatch* pContact,
   IDispatch* pIMSession
);
[IDL]
void OnSessionMemberLeave(
   [in] IDispatch* pContact,
   [in] IDispatch* pIMSession
);

Remarks

This event is generated when a remote client leaves an IM session. All remaining session members receive this notification.


OnSessionStateChange Method

The OnSessionStateChange method indicates that the state of an IM session on the local client has changed.

[Visual Basic,VBScript]
Event OnSessionStateChange(
   pIMSession As Object,
   lPrevState As Long
)
[C++]
void OnSessionStateChange(
   IDispatch* pIMSession,
   long lPrevState
);
[IDL]
void OnSessionStateChange(
   [in] IDispatch* pIMSession,
   [in] long lPrevState
);
lPrevState
A value of the IM_SSTATE enumeration specifying the previous state of the session.

Remarks

This notification is received by the local client only when an existing IM session changes its state, not when a new session is created. For example, if a local client closes a session’s IMWindow, only the local client receives the OnSessionStateChange notification. Other members of the session receive a DIMServiceEvents::OnSessionMemberLeave notification when the local client leaves the session, because, from their perspective, the session is still connected.


OnTextReceived Method

The OnTextReceived method indicates that text has been received from a contact connected to the server, or from the server itself.

[Visual Basic,VBScript]
Event OnTextReceived(
   pIMSession As Object,
   pContact As Object,
   bstrMsgHeader As String,
   bstrMsgText As String,
   pfHandled As Variant
)
[C++]
void OnTextReceived(
   IDispatch* pIMSession,
   IDispatch* pContact,
   BSTR bstrMsgHeader,
   BSTR bstrMsgText,
   VARIANT* pfHandled
);
[IDL]
void OnTextReceived(
   [in] IDispatch* pIMSession,
   [in] IDispatch* pContact,
   [in] BSTR bstrMsgHeader,
   [in] BSTR bstrMsgText,
   [in, out] VARIANT* pfHandled
);
bstrMsgHeader
The header string of the incoming Instant Message. (See IIMContact::SendText for a description of valid header syntax.)
bstrMsgText
A string containing the text of the Instant Message received.
pfHandled
A flag that determines whether the event has been handled by another client application.

Remarks

Each incoming Instant Message generates a separate OnTextReceived notification, even if all the Instant Messages are contained in the same session.


DMSIMContactViewEvents Interface

The DMSIMContactViewEvents interface is a dispinterface that handles notifications that are generated or received by an MSIMContactView object.

IID
5D39E512-1068-4F85-8173-357CA1892EE2
Extends
IDispatch

Methods

Name | Description
OnAddContactUI | Indicates that the add contact user interface (UI) is starting.
OnAddResult | Indicates that a contact has been added, or that an addition was attempted.
OnEMailContact | Indicates that the user has requested to send e-mail to a contact using a mailto: URL.
OnExtentsChange | Indicates that the size of the list has changed.
OnLocalStateChange | Indicates that the state for the local user has changed, or that a state change was attempted.
OnLaunchMessageUI | Indicates that the local user has requested a new Microsoft® Exchange 2000 Instant Messaging Service (IM) or Microsoft® NetMeeting® session with a contact.
OnLogoff | Indicates that the local user has logged off from an IM service provider.
OnLogon | Indicates that the local user has attempted to log on to an IM service provider.
OnMenuRequest | Indicates that a context menu is about to be displayed.
OnMenuSelect | Indicates that a custom context menu item has been selected.
OnReady | Indicates that the IM list UI is initialized.
OnRemoveResult | Indicates that a contact has been removed, or that a removal was attempted.
OnSelect | Indicates that a root label or a contact on the IM list has been selected.
OnShutdown | Indicates that the IM list control is shutting down.


OnAddContactUI Method

The OnAddContactUI method indicates that the add contact UI is starting.

[Visual Basic,VBScript]
Event OnAddContactUI(pfEnableDefault As Variant)
[C++]
void OnAddContactUI(VARIANT* pfEnableDefault);
[IDL]
void OnAddContactUI([in, out] VARIANT* pfEnableDefault);
pfEnableDefault
The client application can override the default behavior of launching the add contact UI by setting pfEnableDefault to False. To allow the default action to occur, do not set pfEnableDefault to False.

Remarks

The add contact UI is started by invoking the MSIMContactView::Add method with an empty parameter.


OnAddResult Method

The OnAddResult method indicates that a contact has been added, or that an addition was attempted.

[Visual Basic,VBScript]
Event OnAddResult(
   lResult As Long,
   bstrContact As String
)
[C++]
void OnAddResult(
   long lResult,
   BSTR bstrContact
);
[IDL]
void OnAddResult(
   [in] long lResult,
   [in] BSTR bstrContact
);
lResult
The return code that gives the result of the add request. Possible return values are: S_OK (the add was successful), IM_E_USER_NOT_FOUND, or IM_E_ALREADY_IN_LIST.
bstrContact
The IM address of the contact that was added or whose addition to the list was attempted.

Remarks

This event is fired when the IMSIMContactView::Add method is successfully invoked.


OnEMailContact Method

The OnEmailContact method indicates that the user has requested to send e-mail to a contact using a mailto: URL.

[Visual Basic,VBScript]
Event OnEMailContact(
   bstrContact As String,
   pfEnableDefault As Variant
)
[C++]
void OnEMailContact(
   BSTR bstrContact,
   VARIANT* pfEnableDefault
);
[IDL]
void OnEMailContact(
   [in] BSTR bstrContact,
   [in, out] VARIANT* pfEnableDefault
);
bstrContact
The e-mail address of the contact the user selected.
pfEnableDefault
A flag that indicates whether the default action will occur. If pfEnableDefault is set to True, the default action will occur. If pfEnableDefault is set to False, an alternative action defined by the application will occur.

Remarks

The client application can handle the e-mail request for the user by setting pfEnableDefault to False.


OnExtentsChange Method

The OnExtentsChange method indicates that the size of the list has changed.

[Visual Basic,VBScript]
Event OnExtentsChange(
   nWidth As Long,
   nHeight As Long
)
[C++]
void OnExtentsChange(
   long nWidth,
   long nHeight
);
[IDL]
void OnExtentsChange(
   [in] long nWidth,
   [in] long nHeight
);
nWidth
The width of the visual area of the control in pixels.
nHeight
The height of the visual area of the control in pixels.

Remarks

This event indicates that the size required of the window in order to show the entire list without clipping has changed. For example, if a contact is added or removed from the list, or the online or offline nodes are expanded, the size requirements of the window change. An application can use this event to resize the containing window to show the entire list without clipping.

This method can be used to automatically set the size of the object.

<html>
<body>
<object
classid=clsid:B06EDBC7-287D-405C-A899-9C7F8358EF26
     id=MSIMContactView>
</object>
</body>
<script language=VBSCRIPT>
     SUB MSIMContactView_OnExtentsChange(BYVAL nWidth, BYVAL nHeight)
          if chkAutoSize.checked Then
               MSIMContactView.height = Min(nHeight, 300)
               MSIMContactView.width = Min(nWidth, 300)
          End If
     End SUB
</script>
</html>
© 2000-2001 Microsoft Corporation. All rights reserved.


OnLaunchMessageUI Method

The OnLaunchMessageUI method indicates that the local user has requested a new IM or NetMeeting session with a contact.

[Visual Basic,VBScript]
Event OnLaunchMessageUI(
   bstrContact As String,
   lFlags As Long,
   pfEnableDefault As Variant
)
[C++]
void OnLaunchMessageUI(
   BSTR bstrContact,
   long lFlags,
   VARIANT* pfEnableDefault
);
[IDL]
void OnLaunchMessageUI(
   [in] BSTR bstrContact,
   [in] long lFlags,
   [in, out] VARIANT* pfEnableDefault
);
bstrContact
The IM address of the contact the user selected.
lFlags
A member of the MSIM_MSG_UI enumeration indicating whether the requested session is an IM session or a NetMeeting session.
pfEnableDefault
A flag that indicates whether the default action will occur. If pfEnableDefault is set to True, the default action will occur. If pfEnableDefault is set to False, an alternative action defined by the application will occur.

The default action when pfEnableDefault is set to True is that an instance of MSIMMessageView loads into an MSIMHost window.

Remarks

An application can override the IM UI by setting pfEnableDefault to False and providing its own UI for sending and receiving messages. Additionally, an application can load the MSIMMessageView control into a custom window that it provides instead of a window provided by MSIMHost.


OnLocalStateChange Method

The OnLocalStateChange method indicates that the state for the local user has changed, or that a state change was attempted.

[Visual Basic,VBScript]
Event OnLocalStateChange(
   lLocalState As Long,
   bstrDescription As String,
   pVarData as Variant
)
[C++]
void OnLocalStateChange(
   long lLocalState,
   BSTR bstrDescription,
   VARIANT* pVarData
);
[IDL]
void OnLocalStateChange(
   [in] long lLocalState,
   [in] BSTR bstrDescription,
   [in] VARIANT *pVarData
);
lLocalState
The current state of the local user. For a list of possible states, see the IM_STATE enumeration.
bstrDescription
A description of the state.
pVarData
Reserved for future use.

Remarks

This event can be fired as a result of either an explicit user call to the _IUseIMBase::GetLocalState method or by logging on or logging off.


OnLogoff Method

The OnLogoff method indicates that the local user has logged off from an IM service provider.

[Visual Basic,VBScript]
Event OnLogoff(lResult As Long)
[C++]
void OnLogoff(long lResult);
[IDL]
void OnLogoff([in] long lResult);
lResult
The return code that gives the result of the request. Possible return values for this parameter include S_OK and IM_E_DISCONNECTED.


OnLogon Method

The OnLogon method indicates that the local user has attempted to log on to an IM service provider.

[Visual Basic,VBScript]
Event OnLogon(lResult As Long)
[C++]
void OnLogon(long lResult);
[IDL]
void OnLogon([in] long lResult);
lResult
The return code that gives the result of the request. Possible return values for this parameter include: S_OK, IM_E_USER_CANCELLED_LOGON, IM_E_INVALID_PASSWORD, IM_E_INVALID_SERVER_NAME, IM_E_CONNECT, E_FAIL, E_OUT_OF_MEMORY, and E_INVALIDARG.


OnMenuRequest Method

The OnMenuRequest method indicates that a context menu is about to be displayed.

[Visual Basic,VBScript]
Event OnMenuRequest(
   bstrContact As String,
   pbfDefaults As Variant
)
[C++]
void OnMenuRequest(
   BSTR bstrContact,
   VARIANT* pbfDefaults
);
[IDL]
void OnMenuRequest(
   [in] BSTR bstrContact,
   [in, out] VARIANT* pbfDefaults
);
bstrContact
The IM address of the contact the user selected.
pbfDefaults
The flags indicating which options are enabled by default on the context menu.

Remarks

The value returned by the pbfDefaults parameter corresponds to the sum of the values associated with the default context menu items enabled for a particular contact. The following table outlines the values associated with the default menu items.

Name | Value | Description
IDM_SEND_IM | 0x0F01 | Sends an IM invitation.
IDM_SEND_EMAIL | 0x0F02 | Sends an e-mail message.
IDM_INVITE | 0x0F04 | Invites a contact to join NetMeeting.
IDM_BLOCK | 0x0F08 | Adds a contact to the user’s Block list.
IDM_DELETE | 0x0F10 | Deletes a contact from the contact list.
IDM_ADD_USER | 0x0F20 | Adds a contact to the contact list.
IDM_LOGOFF | 0x0F40 | Logs a user off from IM.

To add menu items, an application must call IMSIMContactView::AddMenuItem in this method.

Example

[VBScript]
DIM Cmd1
DIM Cmd2

SUB MSIMContactView_OnMenuRequest(BYVAL strSelected, BYREF pbfDefaults)
     Dim Sep
     Cmd1 = MSIMContactView.AddMenuItem("Test Item 1")
     Sep = MSIMContactView.AddMenuItem("")
     Cmd2 = MSIMContactView.AddMenuItem("Test Item 2")
END SUB

SUB MSIMContactView_OnMenuSelect(BYVAL strSelected, BYVAL lCmd)
     if Cmd1 = lCmd then
          ' Do command one
     elseif Cmd2 = lCmd then
          ' Do command two
     endif
END SUB
© 2000-2001 Microsoft Corporation. All rights reserved.


OnMenuSelect Method

The OnMenuSelect method indicates that a custom context menu item has been selected.

[Visual Basic,VBScript]
Event OnMenuSelect(
   bstrContact As String,
   lCmd As Long
)
[C++]
void OnMenuSelect(
   BSTR bstrContact,
   long lCmd
);
[IDL]
void OnMenuSelect(
   [in] BSTR bstrContact,
   [in] long lCmd
);
bstrContact
The IM address of the contact the user selected.
lCmd
The selected context menu item.

Remarks

This event fires when a command that was added with IMSIMContactView::AddMenuItem is chosen. The lCmd parameter returns the plCommand identifier generated by IMSIMContactView::AddMenuItem.

Example

[VBScript]
DIM Cmd1
DIM Cmd2

SUB MSIMContactView_OnMenuRequest(BYVAL strSelected, BYREF pbfDefaults)
     Dim Sep
     Cmd1 = MSIMContactView.AddMenuItem("Test Item 1", 0)
     Sep = MSIMContactView.AddMenuItem("")
     Cmd2 = MSIMContactView.AddMenuItem("Test Item 2")
END SUB

SUB MSIMContactView_OnMenuSelect(BYVAL strSelected, BYVAL lCmd)
     if Cmd1 = lCmd then
          ' Do command one
     elseif Cmd2 = lCmd then
          ' Do command two
     endif
END SUB
© 2000-2001 Microsoft Corporation. All rights reserved.


OnReady Method

The OnReady method indicates that the IM list UI is initialized.

[Visual Basic,VBScript]
Event OnReady()
[C++]
void OnReady();
[IDL]
void OnReady();

Remarks

This event is called when a service provider is set and loaded, and the UI is active. A client application should not make calls to any MSIMContactView methods until this event is received.


OnRemoveResult Method

The OnRemoveResult method indicates that a contact has been removed, or that a removal was attempted.

[Visual Basic,VBScript]
Event OnRemoveResult(
   lResult As Long,
   bstrContact As String
)
[C++]
void OnRemoveResult(
   long lResult;
   BSTR bstrContact
);
[IDL]
void OnRemoveResult(
   [in] long lResult;
   [in] BSTR bstrContact
);
lResult
The return code that gives the result of the request.
bstrContact
The IM address of the contact the user selected.


OnSelect Method

The OnSelect method indicates that a root label or a contact on the IM list has been selected.

[Visual Basic,VBScript]
Event OnSelect(bstrContact As String)
[C++]
void OnSelect(BSTR bstrContact);
[IDL]
void OnSelect([in] BSTR bstrContact);
bstrContact
The IM address of a contact, or the online or offline root node.

Remarks

The online and offline root labels are treated as contacts with their own context menus. When an online or offline root label is selected, the OnSelect event will fire with bstrContact set to ONLINE for the online root label, and OFFLINE for the offline root label.

Every time a contact list is loaded using the IIMService::List method, OnSelect will fire for each contact in the list.

After calling the IMSIMContactView::Add method, OnSelect will fire for the newly added contact.

After calling the IMSIMContactView::Remove method, OnSelect will fire for the next contact in the list. If the online or offline root node is the next contact in the list, OnSelect will also fire.


OnShutdown Method

The OnShutdown method indicates that the IMSIMHost is shutting down.

[Visual Basic,VBScript]
Event OnShutdown()
[C++]
HRESULT OnShutdown();
[IDL]
HRESULT OnShutdown();

Remarks

The Contact View control appears as logged off when the IMSIMHost is shut down.


DMSIMHostEvents Interface

The DMSIMHostEvents interface provides notifications on the state of the host application.

IID
E27DE165-A199-4427-A38F-BEED080AC9D4
Extends
IDispatch

Member Summary

Methods

Name | Description
OnClickUserNotify | Indicates that a user has clicked a notify window.
OnDoubleClick | Indicates that the local user has double-clicked the MSIMHost tray icon.
OnShutdown | Indicates that the local user is closing the application.


OnClickUserNotify Method

The OnClickUserNotify method indicates that a user has clicked a notify window.

[Visual Basic,VBScript]
Event OnClickUserNotify(lCookie As Long)
[C++]
void OnClickUserNotify(long lCookie);
[IDL]
void OnClickUserNotify([in] long lCookie);
lCookie
The cookie generated by IMSIMHost::PopupMessage.

Remarks

This notification is sent only if the IMSIMHost::PopupMessage method is called with fClick=True.


OnDoubleClick Method

The OnDoubleClick method indicates that the local user has double-clicked the MSIMHost tray icon.

[Visual Basic,VBScript]
Event OnDoubleClick(pfHandled As Variant);
[C++]
void OnDoubleClick(VARIANT* pfHandled);
[IDL]
void OnDoubleClick([in, out] VARIANT* pfHandled);
pfHandled
A flag that determines whether the event has been handled by another client application.


OnShutdown Method

The OnShutdown method indicates that the local user is closing the application.

[Visual Basic,VBScript]
Event OnShutdown();
[C++]
void OnShutdown();
[IDL]
void OnShutdown();


DMSIMMessageViewEvents Interface

The DMSIMMessageViewEvents interface is a dispinterface that handles notifications that are generated or received by an MSIMMessageView object.

IID
EFFE4FAB-E75C-46EC-AB15-582CD469EB08
Extends
IDispatch

Methods

Name | Description
OnAddResult | Indicates that a contact has been added to a list, or that an addition was attempted.
OnLaunchMessageUI | Indicates that the local user has requested a new Microsoft® Exchange 2000 Instant Messaging Service (IM) or Microsoft® NetMeeting® session with a contact.
OnLocalStateChange | Indicates that the state for the local user has changed, or that a state change was attempted.
OnLogoff | Indicates that the local user has logged off from an IM service provider.
OnLogon | Indicates that the local user has logged on to an IM service provider.
OnNewSession | Indicates that a new IM session has started in the Message View.
OnReady | Indicates that the IM list user interface (UI) is initialized.
OnRemoveResult | Indicates that a contact or list has been removed, or that a removal was attempted.
OnSessionEnd | Indicates that the IM session in the Message View has ended.
OnShutdown | Indicates that the IM list control is shutting down.


OnAddResult Method

The OnAddResult method indicates that a contact has been added to a list, or that an addition was attempted.

[Visual Basic,VBScript]
Event OnAddResult(
   lResult As Long,
   bstrContact As String
)
[C++]
void OnAddResult(
   long lResult,
   BSTR bstrContact
);
[IDL]
void OnAddResult(
   [in] long lResult,
   [in] BSTR bstrContact
);
lResult
The return code that gives the result of the add request.
bstrContact
The contact that has been added to the list.


OnLaunchMessageUI Method

The OnLaunchMessageUI method indicates that the local user has requested a new IM or NetMeeting session with a contact.

[Visual Basic,VBScript]
Event OnLaunchMessageUI(
   bstrContact As String,
   lFlags As Long
   pfEnableDefault As Variant
)
[C++]
void OnLaunchMessageUI(
   BSTR bstrContact,
   long lFlags,
   VARIANT* pfEnableDefault
);
[IDL]
void OnLaunchMessageUI(
   [in] BSTR bstrContact,
   [in] long lFlags,
   [in, out] VARIANT *pfEnableDefault
);
bstrContact
The contact that requested the new IM session.
lFlags
A member of the MSIM_MSG_UI enumeration indicating whether the requested session is an IM session or a NetMeeting session.
pfEnableDefault
A flag that indicates whether the default action will occur. If pfEnableDefault is set to True, the default action will occur. If pfEnableDefault is set to False, an alternative action defined by the application will occur.

Remarks

An application can override the IM UI by setting pfEnableDefault to False and providing its own UI for sending and receiving messages. Additionally, an application can load the MSIMMessageView control into a custom window that it provides instead of a window provided by MSIMHost.


OnLocalStateChange Method

The OnLocalStateChange method indicates that the state for the local user has changed, or that a state change was attempted.

[Visual Basic,VBScript]
Event OnLocalStateChange(
   lLocalState As Long
   bstrDescription As String
   pvarData As Variant
)
[C++]
void OnLocalStateChange(
   long lLocalState,
   BSTR bstrDescription,
   VARIANT *pvarData
);
[IDL]
void OnLocalStateChange(
   [in] long lLocalState,
   [in] BSTR bstrDescription,
   [in] VARIANT *pvarData
);
lLocalState
A member of the IM_STATE enumeration containing the current state of the local user.
bstrDescription
A description of the state.
pvarData
Reserved for future use.

Remarks

This event can be fired as a result of either an explicit user call to the _IUseIMBase::GetLocalState method or by logging on or logging off.


OnLogoff Method

The OnLogoff method indicates that the local user has logged off from an IM service provider.

[Visual Basic,VBScript]
Event OnLogoff(lResult As Long)
[C++]
void OnLogoff(long lResult);
[IDL]
void OnLogoff([in] long lResult);
lResult
The return code that gives the result of the request.


OnLogon Method

The OnLogon method indicates that the local user has logged on to an IM service provider.

[Visual Basic,VBScript]
Event OnLogon(lResult As Long)
[C++]
void OnLogon(long lResult);
[IDL]
void OnLogon([in] long lResult);
lResult
The return code that gives the result of the request.


OnNewSession Method

The OnNewSession method indicates that a new IM session has started in the Message View.

[Visual Basic,VBScript]
Event OnNewSession()
[C++]
void OnNewSession();
[IDL]
void OnNewSession();


OnReady Method

The OnReady method indicates that the IM list UI is initialized.

[Visual Basic,VBScript]
Event OnReady()
[C++]
void OnReady();
[IDL]
void OnReady();

Remarks

This event is fired after a service provider is set and loaded, and the UI is active. A client application should not make calls to any of the MSIMContactView methods until this event is received.


OnRemoveResult Method

The OnRemoveResult method indicates that a contact has been removed, or that a removal was attempted.

[Visual Basic,VBScript]
Event OnRemoveResult(
   lResult As Long,
   bstrContact As String
)
[C++]
void OnRemoveResult(
   long lResult,
   BSTR bstrContact
);
[IDL]
void OnRemoveResult(
   [in] long lResult,
   [in] BSTR bstrContact
);
lResult
The return code that gives the result of the request.
bstrContact
The contact that was removed.


OnSessionEnd Method

The OnSessionEnd method indicates that the IM session in the Message View has ended.

[Visual Basic,VBScript]
Event OnSessionEnd()
[C++]
HRESULT OnSessionEnd();
[IDL]
HRESULT OnSessionEnd();


OnShutdown Method

The OnShutdown method indicates that the IM list control is shutting down.

[Visual Basic,VBScript]
Event OnShutdown()
[C++]
HRESULT OnShutdown();
[IDL]
HRESULT OnShutdown();


DMSIMWindowEvents Interface

The DMSIMWindowEvents interface provides notifications on changes to an MSIMWindow object.

IID
D7417B39-EBB1-45a7-88C9-B69A7DC6E3BB
Extends
IDispatch

Member Summary

Methods

Name | Description
OnClose | Indicates that a user or application requested the window to close.
OnFocus | Indicates that the window has received or lost focus.
OnMove | Indicates that the window was moved.
OnResize | Indicates that the window was resized.
OnShow | Indicates that the window was displayed.


OnClose Method

The OnClose method indicates that a user or application requested the window to close.

[Visual Basic,VBScript]
Event OnClose(
   lWindow As Long,
   pfAllow As Variant
);
[C++]
void OnClose(
   long lWindow,
   VARIANT* pfAllow
);
[IDL]
void OnClose(
   [in] long lWindow,
   [in, out] VARIANT *pfAllow
);
lWindow
A unique identifier for the window equal to the value returned by the IMSIMWindow::Window property.
pfAllow
A flag that indicates whether the window is allowed to close. When set to True, the window is allowed to close. When set to False, the window is prevented from closing.


OnFocus Method

The OnFocus method indicates that the window has received or lost focus.

[Visual Basic,VBScript]
Event OnFocus(
   lWindow As Long,
   fSet As Boolean
);
[C++]
void OnFocus(
   long lWindow,
   VARIANT_BOOL fSet
);
[IDL]
void OnFocus(
   [in] long lWindow,
   [in] VARIANT_BOOL fSet
);
lWindow
A unique identifier for the window equal to the value returned by the IMSIMWindow::Window property.
fSet
A flag indicating whether the window has focus. When set to True, the window has focus. When set to False, the window does not have focus.

Remarks

This event fires each time the window changes focus.


OnMove Method

The OnMove method indicates that the window was moved.

[Visual Basic,VBScript]
Event OnMove(
   lWindow As Long,
   lPosX As Long,
   lPosY As Long
);
[C++]
void OnMove(
   long lWindow,
   long lPosX,
   long lPosY
);
[IDL]
void OnMove(
   [in] long lWindow,
   [in] long lPosX,
   [in] long lPosY
);
lWindow
A unique identifier for the window equal to the value returned by the IMSIMWindow::Window property.
lPosX
The new x coordinate for the window.
lPosY
The new y coordinate for the window.


OnResize Method

The OnResize method indicates that the window was resized.

[Visual Basic,VBScript]
Event OnResize(
   lWindow As Long,
   lType As Long,
   lWidth As Long,
   lHeight As Long
);
[C++]
void OnResize(
   long lWindow,
   long lType,
   long lWidth,
   long lHeight
);
[IDL]
void OnResize(
   [in] long lWindow,
   [in] long lType,
   [in] long lWidth,
   [in] long lHeight
);
lWindow
A unique identifier for the window equal to the value returned by the IMSIMWindow::Window property.
lType
A member of the MSIMWND_SIZE_TYPE enumeration specifying the action the user performed on the window.
lWidth
The new width of the window in pixels.
lHeight
The new height of the window in pixels.


OnShow Method

The OnShow method indicates that the window was displayed.

[Visual Basic,VBScript]
Event OnShow(
   lWindow As Long,
   fShow As Boolean
);
[C++]
void OnShow(
   long lWindow,
   VARIANT_BOOL fShow
);
[IDL]
void OnShow(
   [in] long lWindow,
   [in] VARIANT_BOOL fShow
);
lWindow
A unique identifier for the window equal to the value returned by the IMSIMWindow::Window property.
fShow
A flag indicating if the window is visible. When set to True, the window is showing. When set to False, the window is hiding.


IIMContact Interface

The IIMContact interface defines properties and methods used to access individual Contact objects.

IID
B419C5AC-8B72-482c-8430-4D812DC587EA
Extends
IDispatch

Member Summary

Properties

Name | Type | Description
EmailAddress (Read-Only) | [Visual Basic,VBScript] String [C++,IDL] BSTR | Returns the e-mail address of a Contact object.
FriendlyName | [Visual Basic,VBScript] String [C++,IDL] BSTR | The friendly name of a Contact object.
LogonName (Read-Only) | [Visual Basic,VBScript] String [C++,IDL] BSTR | Returns the IM address of the user.
Service (Read-Only) | [Visual Basic,VBScript] Object [C++,IDL] IDispatch** | Returns the service of the contact as a Service object.
State (Read-Only) | [Visual Basic,VBScript] IM_STATE [C++,IDL] IM_STATE | Returns the IM_STATE (connection state) of a contact.

Methods

Name | Description
SendText | Sends an Instant Message to a Contact object.


EmailAddress Property

The EmailAddress property returns the e-mail address of a Contact object.

[Visual Basic,VBScript]
Property EmailAddress As String
read-only
[C++]
HRESULT get_EmailAddress(BSTR* pbstrEmailAddress);
[IDL]
HRESULT [propget] EmailAddress([out, retval] BSTR* pbstrEmailAddress);


FriendlyName Property

The FriendlyName property contains the friendly name of a Contact object.

[Visual Basic,VBScript]
Property FriendlyName As String
[C++]
HRESULT get_FriendlyName(BSTR* pbstrFriendlyName);
HRESULT put_FriendlyName(BSTR bstrFriendlyName);
[IDL]
HRESULT [propget] FriendlyName([out, retval] BSTR* pbstrFriendlyName);
HRESULT [propput] FriendlyName([in] BSTR bstrFriendlyName);


LogonName Property

The LogonName property returns the IM address of the user.

[Visual Basic,VBScript]
Property LogonName As String
read-only
[C++]
HRESULT get_LogonName(BSTR* pbstrLogonName);
[IDL]
HRESULT [propget] get_LogonName([out, retval] BSTR* pbstrLogonName);


Service Property

The Service property returns the service of the contact as a Service object.

[Visual Basic,VBScript]
Property Service as Object
read-only
[C++]
HRESULT get_Service(IDispatch** ppService);
[IDL]
HRESULT [propget] Service([out, retval] IDispatch** ppService);


State Property

The State property returns the IM_STATE (connection state) of a contact.

[Visual Basic,VBScript]
Property State as IM_STATE
read-only
[C++]
HRESULT get_State(IM_STATE* pmState);
[IDL]
HRESULT get_State([out, retval] IM_STATE* pmState);


SendText Method

The SendText method sends an Instant Message to a Contact object.

[Visual Basic,VBScript]
Function SendText(
   bstrMsgHeader As String,
   bstrMsgText As String,
   MsgType As IM_MSG_TYPE
) As LONG
[C++]
HRESULT SendText(
   BSTR bstrMsgHeader,
   BSTR bstrMsgText,
   IM_MSG_TYPE MsgType,
   LONG* plCookie
);
[IDL]
HRESULT SendText(
   [in] BSTR bstrMsgHeader,
   [in] BSTR bstrMsgText,
   [in] IM_MSG_TYPE MsgType,
   [out, retval] LONG* plCookie
);
bstrMsgHeader
A header that contains MIME information for the message that is contained in bstrMsgText.
bstrMsgText
A string containing the text of the message.
MsgType
A value from the IM_MSG_TYPE enumeration.
plCookie
A pointer to a unique numerical identifier that correlates this message to notifications sent in response to the message.

Remarks

Before calling this method, a session must have already been established with the contact.

The bstrMsgHeader must be formatted as follows:

"MIME-Version: 1.0"
"Content-Type: text/plain"

Note the trailing extra return (CR) character.

The following additional MIME types are also supported. Substitute these MIME strings in the preceding example:

"Content-Type: text/plain; charset=UTF-8"
"Content-Type: text/html"
"Content-Type: text/html; charset=UTF-8"

The following is an example of the valid header string:

CComBSTR MyHeader = "MIME-Version: 1.0\r\nContent-Type: text/plain; charset=UTF-8\r\n\r\n"


IIMContacts Interface

The IIMContacts interface defines properties and methods used to access a collection of Instant Messaging (IM) contacts.

IID
89FE8208-B3F8-4096-A482-159DF13DF62A
Extends
IDispatch

Member Summary

Properties

Name | Type | Description
Cookie (Read-Only) | [Visual Basic,VBScript] Long [C++,IDL] long | Returns a unique identifier for the collection of contacts.
Count (Read-Only) | [Visual Basic,VBScript] Long [C++,IDL] long | Returns the total number of contacts in the collection.
Name | [Visual Basic,VBScript] String [C++,IDL] BSTR | A name that uniquely identifies the collection of contacts.
_NewEnum (Read-Only) | [Visual Basic,VBScript] N/A [C++,IDL] IUnknown* | Returns an IEnumVariant interface on an enumeration object. (This property is hidden from Microsoft® Visual Basic® and Visual Basic Scripting Edition (VBScript) and is used in For Each in constructs.)
Properties (Read-Only) | [Visual Basic,VBScript] Long [C++,IDL] long | Indicates how a contact list is created and managed.

Methods

Name | Description
Add | Adds a contact to the collection.
Item | Returns a contact from the collection, specified by the index.
Remove | Removes a contact from the collection.

Remarks

© 2000-2001 Microsoft Corporation. All rights reserved.


Cookie Property

The Cookie property returns a unique identifier for the collection of contacts.

[Visual Basic,VBScript]
Property Cookie As Long
[C++]
HRESULT get_Cookie(long* pVal);
[IDL]
HRESULT [propget] Cookie([out, retval] long* pVal);


Count Property

The Count property returns the total number of contacts in the collection.

[Visual Basic,VBScript]
Property Count As Long
[C++]
HRESULT get_Count(long* pVal);
[IDL]
HRESULT [propget] Count([out, retval] long* pVal);

Remarks

This is a one-based index.


Name Property

The Name property returns or sets a name that uniquely identifies the collection of contacts.

[Visual Basic,VBScript]
Property Name As String
[C++]
HRESULT get_Name(BSTR* pVal);
HRESULT put_Name(BSTR newVal);
[IDL]
HRESULT [propget] Name([out, retval] BSTR* pVal);
HRESULT [propput] Name([in] BSTR newVal);

Example

[Visual Basic]
Public WithEvents oIMServ As MSIMCliSDKLib.MSIMService
Public WithEvents oIMApp As MSIMCliSDKLib.MSIMHost
Dim oIMList as IIMContacts

'create the IM Host object and create a service context
Set oIMApp = CreateObject("MSExchangeIM.MSIMHost")
Set oIMServ = oIMApp.CreateContext("Default", 0)

'logon to the IM service
oIMServ.Logon

'set oIMList to the default contact list - $$Messenger\Contact
Set oIMList = oIMServ.List ("$$Messenger\Contact")

msgbox oIMList.Name


_NewEnum Property

The _NewEnum property returns an IEnumVariant interface on an enumeration object. (This property is hidden from Visual Basic and VBScript and is used in For Each in constructs.)

[Visual Basic,VBScript]
Used automatically in For Each In constructs
[C++]
HRESULT get__NewEnum(IUnknown** ppVal);
[IDL]
HRESULT [propget] _NewEnum([out, retval] IUnknown **ppVal);

Remarks

This property is hidden within Visual Basic and VBScript. It is a standard property that is used to support enumerating collections, such as the For Each in construct in Visual Basic.

Do not use the For Each in construct to delete all contacts in a list. Instead, use the IIMContacts::Remove method.

Example

[Visual Basic]
Dim iCont As IIMContact
Dim iConts As IIMContacts
...
For Each iCont in iConts   ' _NewEnum used internally here
...
Next iCont
© 2000-2001 Microsoft Corporation. All rights reserved.


Properties Property

The Properties property indicates how a contact list is created and managed.

[Visual Basic,VBScript]
Property Properties As Long
read-only
[C++]
HRESULT get_Properties(long* pVal);
[IDL]
HRESULT [propget] Properties([out, retval] long* pVal);


Add Method

The Add method adds a contact to the collection.

[Visual Basic,VBScript]
Sub Add(pContact As Object)
[C++]
HRESULT Add(IDispatch* pContact);
[IDL]
HRESULT Add([in] IDispatch* pContact);

Example

[Visual Basic]
Public WithEvents oIMServ As MSIMCliSDKLib.MSIMService
Public WithEvents oIMApp As MSIMCliSDKLib.MSIMHost
Dim oIMList as IIMContacts
Dim pContact As IIMContact

'create the IM Host object and create a service context
Set oIMApp = CreateObject("MSExchangeIM.MSIMHost")
Set oIMServ = oIMApp.CreateContext("Default", 0)

'logon to the IM service
oIMServ.Logon

'set oIMList to the default contact list - $$Messenger\Contact
Set oIMList = oIMServ.List ("$$Messenger\Contact")
Set pContact = oIMServ.CreateContact("someone@microsoft.com")

'add the user to the list
oIMList.Add pContact


Item Method

The Item method returns a contact from the collection, specified by the index.

[Visual Basic,VBScript]
Function Item(ByVal varItem As Variant) As Object
[C++]
HRESULT Item(
   VARIANT varItem,
   IDispatch** ppContact
);
[IDL]
HRESULT Item(
   [in] VARIANT varItem,
   [out, retval] IDispatch **ppContact
);

Remarks

This is a zero-based index.


Remove Method

The Remove method removes a contact from the collection.

[Visual Basic,VBScript]
Sub Remove(pContact As Object)
[C++]
HRESULT Remove(IDispatch* pContact);
[IDL]
HRESULT Remove([in] IDispatch *pContact);

Example

[Visual Basic]
Public WithEvents oIMServ As MSIMCliSDKLib.MSIMService
Public WithEvents oIMApp As MSIMCliSDKLib.MSIMHost
Dim oIMList as IIMContacts
Dim pContact As IIMContact

'create the IM Host object and create a service context
Set oIMApp = CreateObject("MSExchangeIM.MSIMHost")
Set oIMServ = oIMApp.CreateContext("Default", 0)

Set oIMList = oIMServ.List("$$Messenger\Contact")
Set pContact = oIMServ.CreateContact("someone@microsoft.com")
oIMList.Add pContact
... ' add more contacts to the list

'the following code removes all contacts from a list
While oIMList.Count > 0
     oIMList.Remove oIMList.Item(0)
     If Err.Number <> 0 Then
          MsgBox "Remove: " & CStr(Err.Number) & " " & Err.Description
     End If
Wend
© 2000-2001 Microsoft Corporation. All rights reserved.


IIMService Interface

The IIMService interface defines properties and methods used to access Microsoft® Exchange 2000 Instant Messaging Service (IM) options.

IID
2F5FC78B-B85C-43F8-A8F9-C9241869600B
Extends
IDispatch

Member Summary

Properties

Name | Type | Description
BlockByDefault | [Visual Basic,VBScript] Boolean [C++,IDL] VARIANT_BOOL | Indicates that only the contacts on a user’s allow list can monitor the user’s online status.
FriendlyName | [Visual Basic,VBScript] String [C++,IDL] BSTR | The friendly name for the local user.
IMAddress (Read-Only) | [Visual Basic,VBScript] String [C++,IDL] BSTR | Returns the IM address for the local user.
IMSessions (Read-Only) | [Visual Basic,VBScript] IIMSessions [C++,IDL] IIMSessions** | Returns a collection of the current IM sessions.
Server (Read-Only) | [Visual Basic,VBScript] String [C++,IDL] BSTR | Returns the local user’s domain name.

Methods

Name | Description
CreateContact | Creates a new Contact object for the specified IM address.
CreateIMSession | Creates a new IM session with the indicated contact.
FindContact | Initiates a search for a contact indicated by a string or alias.
GetLocalState | Returns the state of the local user and the state’s description.
List | Returns a collection of contacts.
Logoff | Logs a contact off from the IM server.
Logon | Logs a contact on to the IM server.
NewList | Creates a new collection of contacts.
RemoveList | Removes the indicated collection of contacts.
SendNetMeetingAccept | Sends an acceptance message to a remote contact that has invited the local user to join Microsoft® NetMeeting®.
SendNetMeetingCancel | Sends a cancellation message to a remote contact that has invited the local user to join NetMeeting.
SendNetMeetingInvite | Sends an invitation to a remote contact to join NetMeeting.
SetLocalState | Sets the state of the local user.


BlockByDefault Property

The BlockByDefault property indicates that only the contacts on a user’s Allow list can monitor the user’s online status.

[Visual Basic,VBScript]
Property BlockByDefault As Boolean
[C++]
HRESULT get_BlockByDefault (VARIANT_BOOL* pVal);
HRESULT put_BlockByDefault (VARIANT_BOOL newVal);
[IDL]
HRESULT [propget] BlockByDefault ([out, retval] VARIANT_BOOL *pVal);
HRESULT [propput] BlockByDefault ([in] VARIANT_BOOL newVal);

Remarks

When set to True, only the contacts that the user has added to their Allow list are able to monitor the online status of the user. When set to False, any contacts that are not on the user’s Block list are allowed to monitor the user’s online status. The default setting for this property is False.


FriendlyName Property

The FriendlyName property returns and sets the friendly name for the local user.

[Visual Basic,VBScript]
Property FriendlyName As String
[C++]
HRESULT get_FriendlyName(BSTR* pbstrName);
HRESULT put_FriendlyName(BSTR bstrName);
[IDL]
HRESULT [propget] FriendlyName([out, retval] BSTR* pbstrName);
HRESULT [propput] FriendlyName([in] BSTR bstrName);


IMAddress Property

The IMAddress property returns the IM address for the local user.

[Visual Basic,VBScript]
Property IMAddress as String
read-only
[C++]
HRESULT get_IMAddress(BSTR* pbstrName);
[IDL]
HRESULT [propget] IMAddress([out, retval] BSTR* pbstrName);


IMSessions Property

The IMSessions property returns a collection of the current IM sessions.

[Visual Basic,VBScript]
Property IMSessions As Object
read-only
[C++]
HRESULT get_IMSessions(IDispatch ** ppIMSessions);
[IDL]
HRESULT [propget] IMSessions([out, retval] IDispatch** ppIMSessions);


Server Property

The Server property returns the local user’s domain name.

[Visual Basic,VBScript]
Property Server As String
read-only
[C++]
HRESULT get_Server(BSTR *pbstrName);
[IDL]
HRESULT Server([out, retval] BSTR* pbstrName);


CreateContact Method

The CreateContact method creates a new Contact object for the specified IM address.

[Visual Basic,VBScript]
Function CreateContact(ByVal bstrAlias As String) As Object
[C++]
HRESULT CreateContact(
   BSTR bstrAlias,
   IDispatch** ppContact
);
[IDL]
HRESULT CreateContact(
   [in] BSTR bstrAlias,
   [out, retval] IDispatch** ppContact
);
bstrAlias
A string containing the alias of the remote contact. The string must contain the at sign (@) and the contact’s domain name.

Remarks

This method simply creates a Contact object; the object is not necessarily a valid contact.

Example

[Visual Basic]
Public WithEvents oIMServ As MSIMCliSDKLib.MSIMService
Public WithEvents oIMApp As MSIMCliSDKLib.MSIMHost
Dim oIMList as IIMContacts
Dim pContact As IIMContact

'create the IM Host object and create a service context
Set oIMApp = CreateObject("MSExchangeIM.MSIMHost")
Set oIMServ = oIMApp.CreateContext("Default", 0)

'logon to the IM service
oIMServ.Logon

'set oIMList to the default contact list
Set oIMList = oIMServ.List ("$$Messenger\Contact")
Set pContact = oIMServ.CreateContact("someone@microsoft.com")

'add the user to the list
oIMList.Add pContact


CreateIMSession Method

The CreateIMSession method creates a new IM session with the indicated contact.

[Visual Basic,VBScript]
Function CreateIMSession(varIMContact As Variant) As Object
[C++]
HRESULT CreateIMSession(
   VARIANT varIMContact,
   IDispatch ** ppIMSession
);
[IDL]
HRESULT CreateIMSession(
   [in] VARIANT varIMContact,
   [out, retval] IDispatch** ppIMSession
);
varIMContact
A Contact object or the IM address string of a contact. If the input value type is a string, this method calls the IIMService::CreateContact method internally to create a new Contact object, and then establishes a new IM session with that contact.


FindContact Method

The FindContact method initiates a search for a contact indicated by a string or alias.

[Visual Basic,VBScript]
Function FindContact(
   ByVal bstrFirstName As String,
   ByVal bstrLastName As String,
   ByVal bstrAlias As String
   ByVal bstrCity As String,
   ByVal bstrState As String,
   ByVal bstrCountry As String
) As Long
[C++]
HRESULT FindContact(
   BSTR  bstrFirstName,
   BSTR  bstrLastName,
   BSTR bstrAlias
   BSTR  bstrCity,
   BSTR  bstrState,
   BSTR  bstrCountry,
   LONG*  plCookie
);
[IDL]
HRESULT FindContact(
   [in] BSTR bstrFirstName,
   [in] BSTR bstrLastName,
   [in] BSTR bstrAlias
   [in] BSTR bstrCity,
   [in] BSTR bstrState,
   [in] BSTR bstrCountry,
   [out, retval] LONG* plCookie
);
bstrFirstName
A string specifying the first name of the contact to find.
bstrLastName
A string specifying the last name of the contact to find.
bstrAlias
A string specifying the alias or e-mail address of the contact to find.
bstrCity
Reserved for future use.
bstrState
Reserved for future use.
bstrCountry
Reserved for future use.
plCookie
A pointer to a unique identifier that is generated by the local client to correlate this request with a DIMServiceEvents::OnFindResult notification.

Remarks

You must include a value for at least one of the following parameters: bstrFirstName, bstrLastName, or bstrAlias. Leaving all three empty or null returns an error.


GetLocalState Method

The GetLocalState method returns the state of the local user and the state’s description.

[Visual Basic,VBScript]
Sub GetLocalState(
   pvarState As Variant,
   [pvarDescription As Variant]
   [pvarData As Variant]
)
[C++]
HRESULT GetLocalState(
   VARIANT* pvarState,
   VARIANT* pvarDescription,
   VARIANT* pvarData
);
[IDL]
HRESULT GetLocalState(
   [out] VARIANT* pvarState,
   [out, pointer_default(ptr), optional] VARIANT* pvarDescription,
   [out, pointer_default(ptr), optional] VARIANT* pvarData
);
pvarState
A member of the IM_STATE enumeration.
pvarDescription
A description of the state, generated by MSIMHost.
pvarData
Reserved for future use.


List Method

The List method returns a collection of contacts.

[Visual Basic,VBScript]
Function List(ByVal bstrListName As String) As Object
[C++]
HRESULT List(
   BSTR bstrListName,
   IDispatch** ppList
);
[IDL]
HRESULT List(
   [in] BSTR bstrListName,
   [out, retval] IDispatch** ppList
);
bstrListName
The name of the list to return.


Logoff Method

The Logoff method logs a contact off from the IM server.

[Visual Basic,VBScript]
Sub Logoff()
[C++]
HRESULT Logoff();
[IDL]
HRESULT Logoff();

Remarks

Successfully invoking this method results in a DIMServiceEvents::OnLogoff notification as well as a DIMServiceEvents::OnLocalStateChangeResult notification. The Onlogoff event must fire before the IIMService::Logon method is called to log a user back on to the IM server.


Logon Method

The Logon method logs a contact on to the IM server.

[Visual Basic,VBScript]
Sub Logon([ByVal varParameter As Variant])
[C++]
HRESULT Logon(VARIANT varParameter);
[IDL]
HRESULT Logon([in, optional] VARIANT varParameter);
varParameter
This parameter can be any of the following:
  • An empty Variant. In this case, the IM address, logon name, and domain information will be read in from the registry and used.
  • A BSTR Variant containing the IM address to use. This will attempt to use the local user credentials to authenticate.
  • A Variant containing an array of BSTRs where:
    varParameter(0) = The IM address of the local user to be logged on.
    varParameter(1) = The logon name of the local user.
    varParameter(2) = The password for the local user.
    varParameter(3) = The domain of the local user.

Remarks

Successfully invoking this method results in a DIMServiceEvents::OnLogonResult notification, as well as a DIMServiceEvents::OnLocalStateChangeResult notification.

After a user has logged off the IM server, the DIMServiceEvents::OnLogoff event must fire before Logon is called to log the user back on to the IM server.


NewList Method

The NewList method creates a new collection of contacts.

[Visual Basic,VBScript]
Function NewList(
   ByVal bstrListName As String,
   ByVal bfProperties As Long
) As Object
[C++]
HRESULT NewList(
   BSTR bstrListName,
   long bfProperties,
   IDispatch** ppList
);
[IDL]
HRESULT NewList(
   [in] BSTR bstrListName,
   [in] long bfProperties,
   [out, retval] IDispatch **ppList
);
bstrListName
A string containing the name of the list.
bfProperties
MSIM_LIST_CONTACT or MSIM_LIST_CONTACT | MSIM_LIST_NOREF from the MSIM_LIST_TYPE enumeration. These are the only valid members of the MSIM_LIST_TYPE enumeration for this parameter.

When using MSIM_LIST_CONTACT | MSIM_LIST_NOREF, once the reference to the list has been released, the list cannot be retrieved.

Example

[Visual Basic]
Public WithEvents oIMServ As MSIMCliSDKLib.MSIMService
Public WithEvents oIMApp As MSIMCliSDKLib.MSIMHost
DIM oIMList as IIMContacts
DIM pContact as IIMContact

Set oIMApp = CreateObject("MSExchangeIM.MSIMHost")
Set oIMServ = oIMApp.CreateContext("Default", 0)

'Create a new list
Set oIMList = oIMServ.NewList ("$$MyList\Contact", 1)

'check to ensure the list was created
If oIMList is Nothing then
    Msgbox "Error creating list."
    Exit sub
End if

'Create a user to add to the list
Set pContact = oIMServ.CreateContact("someone@microsoft.com")

'add the user to the list
oIMList.Add pContact


RemoveList Method

The RemoveList method removes the indicated collection of contacts.

[Visual Basic,VBScript]
Sub RemoveList(ByVal bstrListName As String)
[C++]
HRESULT RemoveList(BSTR bstrListName);
[IDL]
HRESULT RemoveList([in] BSTR bstrListName);

Remarks

This method cannot be used for lists created with MSIM_LIST_NOREF.

See Also

IIMService::NewList

© 2000-2001 Microsoft Corporation. All rights reserved.


SendNetMeetingAccept Method

The SendNetMeetingAccept method sends an acceptance message to a remote contact that has invited the local user to join NetMeeting.

[Visual Basic,VBScript]
Function SendNetMeetingAccept(
   ByVal varContact As Variant,
   ByVal lInviteCookie As Long,
   ByVal lInviteType As Long
) As Long
[C++]
HRESULT SendNetMeetingAccept(
   VARIANT varContact,
   long lInviteCookie,
   long lInviteType,
   long* plSendCookie
);
[IDL]
HRESULT SendNetMeetingAccept(
   [in] VARIANT varContact,
   [in] long lInviteCookie,
   [in] long lInviteType,
   [out, retval] long* plSendCookie
);
varContact
The Contact object that invited the local user to join NetMeeting. This value is obtained through the DIMServiceEvents::OnNetMeetingInviteReceived notification.
lInviteCookie
A numeric identifier used to correlate matching send and receive events. This value is obtained through the DIMServiceEvents::OnNetMeetingInviteAccepted notification.
plSendCookie
A pointer to a numerical identifier for the message. This cookie is generated and incremented automatically by the local client, and is used to track this message through notifications.
lInviteType
A member of the IM_INVITE_FLAGS_TYPE enumeration used to request and send IP address information.


SendNetMeetingCancel Method

The SendNetMeetingCancel method sends a cancellation message to a remote contact that has invited the local user to join NetMeeting.

[Visual Basic,VBScript]
Function SendNetMeetingCancel(
   varContact As Variant,
   lCookie As Long,
   hrReason As Long,
) As Long
[C++]
HRESULT SendNetMeetingCancel(
   VARIANT varContact,
   long lCookie,
   long hrReason,
   long* plSendCookie
);
[IDL]
HRESULT SendNetMeetingCancel(
   [in] VARIANT varContact,
   [in] long lCookie,
   [in] long hrReason,
   [out, retval] long* plSendCookie
);
varContact
The Contact object that invited the local user to join NetMeeting. This value is obtained through the DIMServiceEvents::OnNetMeetingInviteReceived notification.
lCookie
A numeric identifier used to correlate matching send and receive events. This value is obtained through the OnNetMeetingInviteReceived notification, and is passed to the DIMServiceEvents::OnNetMeetingInviteCancelled notification on the remote client.
hrReason
An IM_RESULTS value specifying the appropriate feedback dialog on the remote contact’s computer, explaining why the invitation was rejected.
plSendCookie
A pointer to a numerical identifier for the message. This cookie is generated and incremented automatically by the local client, and is used to track this message through generated events.


SendNetMeetingInvite Method

The SendNetMeetingInvite method sends an invitation to a remote contact to join NetMeeting.

[Visual Basic,VBScript]
Function SendNetMeetingInvite (
   ByVal varContact As Variant,
   ByVal lInviteCookie As Long,
) As Long
[C++]
HRESULT SendNetMeetingInvite (
   VARIANT varContact,
   long lInviteCookie,
   long* plSendCookie
);
[IDL]
HRESULT SendNetMeetingInvite(
   [in] VARIANT varContact,
   [in] long lInviteCookie,
   [out, retval] long* plSendCookie
);
varContact
The remote contact.
lInviteCookie
A numeric identifier used to correlate matching send and receive events. This cookie is passed to the remote client through the DIMServiceEvents::OnNetMeetingInviteReceived notification.

Unlike the plSendCookie parameter, this value is not automatically generated, but must be specified; it is up to the inviting client to ensure that each call to SendNetMeetingInvite has a unique lInviteCookie value. The lInviteCookie value is used to track the progress of this message as an application invitation (such as whether the invitation was accepted or rejected), whereas the plSendCookie value is used to track the progress of this message as a SendText message (such as whether the message was delivered).

plSendCookie
A pointer to a numerical identifier for the message. This cookie is generated and incremented automatically by the local client, and is used to track this message through generated events.


SetLocalState Method

The SetLocalState method sets the state of the local user.

[Visual Basic,VBScript]
Sub SetLocalState(
   lState As Long,
   bstrDescription As String,
   [varData As Variant]
)
[C++]
HRESULT SetLocalState(
   long lState,
   BSTR bstrDescription,
   VARIANT varData
);
[IDL]
HRESULT SetLocalState(
   [in] long lState,
   [in, defaultvalue(“”)] BSTR bstrDescription,
   [in, optional] VARIANT varData
);
lState
One of the following members of the IM_STATE enumeration: IM_STATE_UNKNOWN, IM_STATE_ONLINE, IM_STATE_INVISIBLE, IM_STATE_BUSY, IM_STATE_BE_RIGHT_BACK, IM_STATE_IDLE, IM_STATE_AWAY, IM_STATE_ON_THE_PHONE, IM_STATE_OUT_TO_LUNCH.
bstrDescription
Reserved for future use.
varData
Reserved for future use.

Remarks

Successfully invoking this method results in a DIMServiceEvents::OnLocalStateChangeResult notification each time the state changes. If the state is reset to the same state, the OnLocalStateChangeResult notification does not fire.


IIMSession Interface

The IIMSession interface defines properties and methods used to invite contacts to an Instant Messaging (IM) session, determine a session’s state and contents, and remove current contacts from a session.

IID
8A37FCCA-2087-4b0e-83B2-7A7B63C1D133
Extends
IDispatch

Member Summary

Properties

Name | Type | Description
Invitees (Read-Only) | [Visual Basic,VBScript] Object [C++,IDL] IDispatch** | Returns a collection of contacts that have been invited to an IM session but have not yet returned a notification to the local client.
Members (Read-Only) | [Visual Basic,VBScript] Object [C++,IDL] IDispatch** | Returns a collection of contacts that are members of a session.
Service (Read-Only) | [Visual Basic,VBScript] Object [C++,IDL] IDispatch** | Returns the Service object associated with a session.
State (Read-Only) | [Visual Basic,VBScript] IM_SSTATE [C++,IDL] IM_SSTATE | Returns the IM_SSTATE of a session.

Methods

Name | Description
InviteContact | Invites a Contact object to join an IM session.
LeaveSession | Removes the local user from the active session.
SendText | Sends an Instant Message to all members of the session.


Invitees Property

The Invitees property returns a collection of contacts that have been invited to an IM session but have not yet returned a notification to the local client.

[Visual Basic,VBScript]
Property Invitees As Object
read-only
[C++]
HRESULT get_Invitees(IDispatch** ppContacts);
[IDL]
HRESULT [propget] Invitees([out, retval] IDispatch** ppContacts);


Members Property

The Members property returns a collection of contacts that are members of a session.

[Visual Basic,VBScript]
Property Members As Object
read-only
[C++]
HRESULT get_Members(IDispatch** ppContacts);
[IDL]
HRESULT [propget] Members([out, retval] IDispatch** ppContacts);


Service Property

The Service property returns the Service object associated with a session.

[Visual Basic,VBScript]
Property Service As Object
[C++]
HRESULT get_Service(IDispatch** ppService);
[IDL]
HRESULT [propget] Service([out, retval] IDispatch** ppService);

Remarks

Sessions can only be created within the currently active service, thus all contacts of a session share the same service.


State Property

The State property returns the IM_SSTATE of a session.

[Visual Basic,VBScript]
Property State As IM_SSTATE
[C++]
HRESULT get_State(IM_SSTATE* psState);
[IDL]
HRESULT [propget] State([out, retval] IM_SSTATE* psState);


InviteContact Method

The InviteContact method invites a contact to join an IM session.

[Visual Basic,VBScript]
Sub InviteContact(vContact As VARIANT)
[C++]
HRESULT InviteContact(VARIANT vContact);
[IDL]
HRESULT InviteContact([in] VARIANT vContact);
vContact
A Contact object or the IM address string of a contact. If the input value type is a string, this method calls the IIMService::CreateContact method internally to create a new Contact object, and then establishes a new IM session with that contact.

Remarks

This method is typically used to add contacts to an existing session.


LeaveSession Method

The LeaveSession method removes the current contact from the active session.

[Visual Basic,VBScript]
Sub LeaveSession()
[C++]
HRESULT LeaveSession();
[IDL]
HRESULT LeaveSession();

Remarks

Successfully invoking this method results in a DIMServiceEvents::OnSessionStateChange notification. Other contacts in the session will receive a DIMServiceEvents::OnSessionMemberLeave notification.


SendText Method

The SendText method sends an Instant Message to all members of the session.

[Visual Basic,VBScript]
Function SendText(
   bstrMsgHeader As String,
   bstrMsgText As String,
   MsgType As IM_MSG_TYPE
) As LONG
[C++]
HRESULT SendText(
   BSTR bstrMsgHeader,
   BSTR bstrMsgText,
   IM_MSG_TYPE MsgType,
   LONG* plCookie
);
[IDL]
HRESULT SendText(
   [in] BSTR bstrMsgHeader,
   [in] BSTR bstrMsgText,
   [in] IM_MSG_TYPE MsgType,
   [out, retval] LONG* plCookie
);
bstrMsgHeader
A header that contains MIME information for the message that is contained in bstrMsgText.
bstrMsgText
A string containing the text of the message.
MsgType
A value from the IM_MSG_TYPE enumeration.
plCookie
A pointer to a unique numerical identifier that correlates this message to notifications sent in response to the message.

Remarks

The bstrMsgHeader must be formatted as follows:

"MIME-Version: 1.0"
"Content-Type: text/plain"

Note the trailing extra return (CR) character. The following additional MIME types are also supported. Substitute these MIME strings in the example above:

"Content-Type: text/plain; charset=UTF-8"
"Content-Type: text/html"
"Content-Type: text/html; charset=UTF-8"

The following is an example of the valid header string:

CComBSTR MyHeader = "MIME-Version: 1.0\r\nContent-Type: text/plain; charset=UTF-8\r\n\r\n"


IIMSessions Interface

The IIMSessions interface defines properties and methods used to manage a collection of all current Instant Messaging (IM) sessions.

IID
0E0FC368-285C-4117-953C-1C3C74611FBD
Extends
IDispatch

Member Summary

Properties

Name | Type | Description
Count | [Visual Basic,VBScript] Long [C++,IDL] long | Returns the total number of sessions in the collection.
_NewEnum | [Visual Basic,VBScript] N/A [C++,IDL] IUnknown* | Returns an IEnumVariant interface on an enumeration object. (This property is hidden from Visual® Basic® and Microsoft® Visual Basic® Scripting Edition (VBScript) and is used in For Each in constructs.)

Methods

Name | Description
Item | Returns a session from a collection by index.


Count Property

The Count property returns the total number of sessions in the collection.

[Visual Basic,VBScript]
Property Count As Long
[C++]
HRESULT get_Count(long* pcSessions);
[IDL]
HRESULT [propget] Count([out, retval] long* pcSessions);


_NewEnum Property

The _NewEnum property returns an IEnumVariant interface on an enumeration object. (This property is hidden from Visual® Basic® and Microsoft® Visual Basic® Scripting Edition (VBScript) and is used in For Each in constructs.)

[Visual Basic,VBScript]
Used automatically in For Each In constructs
[C++]
HRESULT get__NewEnum(IUnknown** ppUnknown);
[IDL]
HRESULT _NewEnum([out, retval] IUnknown **ppUnknown);

Remarks

This property is hidden within Visual Basic and VBScript. It is a standard property used to support enumerating collections, such as the For Each in construct in Visual Basic.

Example

[Visual Basic]
Dim iSesn as IIMSession
Dim iSesns as IIMSessions
...
For Each iSesn in iSesns   ' _NewEnum used internally here
...
Next iSesn
© 2000-2001 Microsoft Corporation. All rights reserved.


Item Method

The Item method returns a session from a collection by index.

[Visual Basic,VBScript]
Function Item(ByVal Index As Long) As Object
[C++]
HRESULT Item(
   long  Index,
   IDispatch** ppIMSession
);
[IDL]
HRESULT Item(
   [in] long  Index,
   [out, retval] IDispatch** ppIMSession
);
Index
The ordinal index of the Session object to retrieve.


IMSIMContactView Interface

The IMSIMContactView interface defines properties and methods used to manage an existing MSIMContactView object.

IID
415ADE21-A15F-4C06-8F5D-DD5E0A9EA230
Extends
_IUseIMBase

Member Summary

Properties

Name | Type | Description
AcceptMessages | [Visual Basic,VBScript] Boolean [C++,IDL] VARIANT_BOOL | Obsolete.
AllowCollapse | [Visual Basic,VBScript] Boolean [C++,IDL] VARIANT_BOOL | Indicates whether the root nodes in the list can be expanded and collapsed by the local user.
ExtentHeight (Read-Only) | [Visual Basic,VBScript] Long [C++,IDL] long | Returns the optimal height the control needs to display the list without scroll bars.
ExtentWidth (Read-Only) | [Visual Basic,VBScript] Long [C++,IDL] long | Returns the optimal width the control needs to display the list without scroll bars.
FilterOffline | [Visual Basic,VBScript] Boolean [C++,IDL] VARIANT_BOOL | Indicates whether the offline contacts will be displayed in the list.
Group | [Visual Basic,VBScript] Boolean [C++,IDL] VARIANT_BOOL | Indicates whether the online and offline contacts will be grouped within the respective root nodes in the tree list.
HotTracking | [Visual Basic,VBScript] Boolean [C++,IDL] VARIANT_BOOL | Indicates whether the IM list will track the cursor as it is moved over contacts in the list.
List | [Visual Basic,VBScript] String [C++,IDL] BSTR | The collection to be used in the list.
OfflineCollapsed | [Visual Basic,VBScript] Boolean [C++,IDL] VARIANT_BOOL | Indicates whether the Offline root node will be collapsed or expanded on load.
OfflineRootLabel | [Visual Basic,VBScript] String [C++,IDL] BSTR | Indicates the label to be displayed for the Offline sublist.
OnlineCollapsed | [Visual Basic,VBScript] Boolean [C++,IDL] VARIANT_BOOL | Indicates whether the Online root node will be collapsed or expanded on load.
OnlineRootLabel | [Visual Basic,VBScript] Boolean [C++,IDL] VARIANT_BOOL | Indicates the label to be displayed for the Online sublist.
SelectedMenuOptions (Read-Only) | [Visual Basic,VBScript] Long [C++,IDL] long | Indicates which actions can be performed on a selected contact.
ShowIcons | [Visual Basic,VBScript] Boolean [C++,IDL] VARIANT_BOOL | Indicates whether the state icons are displayed.
ShowLogonButton | [Visual Basic,VBScript] Boolean [C++,IDL] VARIANT_BOOL | Indicates whether a login prompt is displayed if the local user is not already logged on to the IM service provider.
ShowSelectAlways | [Visual Basic,VBScript] Boolean [C++,IDL] VARIANT_BOOL | Indicates whether to continuously show the selection on the list.
Window (Read-Only) | [Visual Basic,VBScript] Long [C++,IDL] long | Returns the handle of the IM window.

Methods

Name | Description
Add | Adds a contact or a list of contacts to the IM list.
AddMenuItem | Adds a menu item to the context menu that is displayed when a selected contact is right-clicked.
BlockSelected | Adds the selected contact to the block list.
EMailSelected | Initiates an e-mail message to the selected contact on the IM list.
IMSelected | Initiates an IM session with the selected contact on the IM list.
InviteSelected | Initiates an invitation to join an application to the selected contact on the IM list.
Remove | Removes a contact from the IM list.
UnblockSelected | Removes the selected contact from the block list.


AcceptMessages Property

Obsolete.

[Visual Basic,VBScript]
Property AcceptMessages as Boolean
[C++]
HRESULT get_AcceptMessages(VARIANT_BOOL* pVal);
HRESULT put_AcceptMessages(VARIANT_BOOL newVal);
[IDL]
HRESULT [propget] AcceptMessages([out, retval] VARIANT_BOOL *pVal);
HRESULT [propput] AcceptMessages([in] VARIANT_BOOL newVal);

Remarks

To handle incoming messages, instead of allowing MSIMHost to handle them for you, set pfHandled to true in the DIMServiceEvents::OnNewSessionRequest method.


AllowCollapse Property

The AllowCollapse property indicates whether the root nodes in the list can be expanded and collapsed by the local user.

[Visual Basic,VBScript]
Property AllowCollapse as Boolean
[C++]
HRESULT get_AllowCollapse(VARIANT_BOOL* pVal);
HRESULT put_AllowCollapse(VARIANT_BOOL newVal);
[IDL]
HRESULT [propget] AllowCollapse([out,retval] VARIANT_BOOL* pVal);
HRESULT [propput] AllowCollapse([in] VARIANT_BOOL newVal);

Remarks

AllowCollapse only applies if the IMSIMContactView.Group property is set to True. However, no error is returned if IMSIMContactView.Group is not set to True.

This property can be set using an HTML <param> tag. The default value when creating a new list is False.


ExtentHeight Property

The ExtentHeight property returns the optimal height in pixels that the control needs in order to display the list without scroll bars.

[Visual Basic,VBScript]
Property ExtentHeight as Long
read-only
[C++]
HRESULT get_ExtentHeight(long* pY);
[IDL]
HRESULT [propget] ExtentHeight([out,retval] long* pY);

Remarks

To allow the control to be displayed in its entirety without clipping, the hosting application needs to set the controls container to the size returned by this property.


ExtentWidth Property

The ExtentWidth property returns the optimal width in pixels that the control needs to display the list without scroll bars.

[Visual Basic,VBScript]
Property ExtentWidth as Long
read-only
[C++]
HRESULT get_ExtentWidth(long* pX);
[IDL]
HRESULT [propget] ExtentWidth([out,retval] long* pX);

Remarks

To allow the control to be displayed in its entirety without clipping, the hosting application needs to set the controls container to the size returned by this property.


FilterOffline Property

The FilterOffline property indicates whether the offline contacts will be displayed in the list.

[Visual Basic,VBScript]
Property FilterOffline as Boolean
[C++]
HRESULT get_FilterOffline(VARIANT_BOOL* pVal);
HRESULT put_FilterOffline(VARIANT_BOOL newVal);
[IDL]
HRESULT [propget] FilterOffline([out,retval] VARIANT_BOOL* pVal);
HRESULT [propput] FilterOffline([in] VARIANT_BOOL newVal);

Remarks

When a contact comes online, they are added to the list. When a contact goes offline, the contact is removed from the online view, but not from the contact list itself.

This property can be set with an HTML <param> tag. The default value when creating a new list is False.


Group Property

The Group property indicates whether the online and offline contacts will be grouped within the respective root nodes in the tree list.

[Visual Basic,VBScript]
Property Group as Boolean
[C++]
HRESULT get_Group(VARIANT_BOOL* pVal);
HRESULT put_Group(VARIANT_BOOL newVal);
[IDL]
HRESULT [propget] Group([out,retval] VARIANT_BOOL* pVal);
HRESULT [propput] Group([in] VARIANT_BOOL* newVal);

Remarks

This property sorts contacts into the online and offline root nodes. Labels for the online and offline root nodes can be set using the IMSIMContactView.OnlineRootLabel and IMSIMContactView.OfflineRootLabel properties. The root nodes are only collapsible if the IMSIMContactView.AllowCollapse property is set to True. To display only the online root node, set the IMSIMContactView.FilterOffline property to True.

This property can be set with an HTML <param> tag. The default value when creating a new list is True.


HotTracking Property

The HotTracking property indicates whether the IM list will track the cursor as it is moved over contacts in the list.

[Visual Basic,VBScript]
Property HotTracking as Boolean
[C++]
HRESULT get_HotTracking(VARIANT_BOOL* pVal);
HRESULT put_HotTracking(VARIANT_BOOL newVal);
[IDL]
HRESULT [propget] HotTracking ([out,retval] VARIANT_BOOL* pVal);
HRESULT [propput] HotTracking ([in] VARIANT_BOOL newVal);

Remarks

When set to True, this property allows a single click on a contact to perform the default action.

This property can be set with an HTML <param> tag. The default value when creating a new list is False.


List Property

The List property contains the collection to be used in the list.

[Visual Basic,VBScript]
Property List as Variant
[C++]
HRESULT get_List(VARIANT* pvarList);
HRESULT put_List(VARIANT varList);
[IDL]
HRESULT [propget] List([out,retval] VARIANT *pvarList);
HRESULT [propput] List([in] VARIANT varList);

Remarks

This property returns the name of the IIMContacts collection. To return the name of the list currently being used, call this property without parameters. To set the list to the local user’s default contact list, set List to $$Messenger\Contact. The following auxiliary lists may also be specified: $$Messenger\Allow, $$Messenger\Block, and $$Messenger\Reverse.

The $$Messenger\Contact, $$Messenger\Allow, $$Messenger\Block, and $$Messenger\Reverse lists are the only lists persisted by the IM service provider, although up to 96 custom lists can be added. The recommended naming scheme for lists is: $$<listname>\[Contact][Allow][Block][Reverse].

This property can be set with an HTML <param> tag.

Example

<html>
<head></head>
<body STYLE="font-family:'MS SANS SERIF';font-size:12">
   <object
      classid=CLSID:B06EDBC7-287D-405C-A899-9C7F8358EF26
      codeType=application/x-oleobject
      width="100%"
      height="100%"
      id=MSIMContactList
      name=MSIMContactList VIEWASTEXT>
      <param NAME="Service" VALUE=0>
      <param NAME="List" VALUE="$$Messenger\Contact">
      <param NAME="FilterOffline" VALUE=True>
      <param NAME="Group" VALUE=False>
   </object>
</body>
</html>
© 2000-2001 Microsoft Corporation. All rights reserved.


OfflineCollapsed Property

The OfflineCollapsed property indicates whether the Offline root node will be collapsed or expanded when the list is loaded.

[Visual Basic,VBScript]
Property OfflineCollapsed as Boolean
[C++]
HRESULT get_OfflineCollapsed(VARIANT_BOOL* pVal);
HRESULT put_OfflineCollapsed(VARIANT_BOOL newVal);
[IDL]
HRESULT [propget] OfflineCollapsed([out,retval] VARIANT_BOOL* pVal);
HRESULT [propput] OfflineCollapsed([in] VARIANT_BOOL newVal);

Remarks

If the OfflineCollapsed property is set to True, the offline node is collapsed. If the property is set to False, the offline node is expanded. The default value when creating a new list is False.

This property can be set with an HTML <param> tag.


OfflineRootLabel Property

The OfflineRootLabel property indicates the label to be displayed for the Offline sublist.

[Visual Basic,VBScript]
Property OfflineRootLabel as String
[C++]
HRESULT get_OfflineRootLabel(BSTR* pbstrLabel);
HRESULT put_OfflineRootLabel(BSTR bstrLabel);
[IDL]
HRESULT [propget] OfflineRootLabel([out,retval] BSTR* pbstrLabel);
HRESULT [propput] OfflineRootLabel([in] BSTR bstrLabel);

Remarks

This property can be set with an HTML <param> tag.


OnlineCollapsed Property

The OnlineCollapsed property indicates whether the Online root node will be collapsed or expanded on load.

[Visual Basic,VBScript]
Property OnlineCollapsed as Boolean
[C++]
HRESULT get_OnlineCollapsed(VARIANT_BOOL* pVal);
HRESULT put_OnlineCollapsed(VARIANT_BOOL newVal);
[IDL]
HRESULT [propget] OnlineCollapsed([out,retval] VARIANT_BOOL* pVal);
HRESULT [propput] OnlineCollapsed([in] VARIANT_BOOL newVal);

Remarks

If the OnlineCollapsed property is set to True, the online node is collapsed. If the property is set to False, the online node is expanded. The default value when creating a new list is False.

This property can be set with an HTML <param> tag.


OnlineRootLabel Property

The OnlineRootLabel property indicates the label to be displayed for the Online sublist.

[Visual Basic,VBScript]
Property OnlineRootLabel as String
[C++]
HRESULT get_OnlineRootLabel(BSTR* pbstrLabel);
HRESULT put_OnlineRootLabel(BSTR bstrLabel);
[IDL]
HRESULT [propget] OnlineRootLabel([out,retval] BSTR* pbstrLabel);
HRESULT [propput] OnlineRootLabel([in] BSTR bstrLabel);

Remarks

This property can be set with an HTML <param> tag.


SelectedMenuOptions Property

The SelectedMenuOptions property indicates which actions can be performed on a selected contact.

[Visual Basic,VBScript]
Property SelectedMenuOptions As Long
read-only
[C++]
HRESULT get_SelectedMenuOptions(long* pVal);
[IDL]
HRESULT [propget] SelectedMenuOptions([out, retval] long *pVal);


ShowIcons Property

The ShowIcons property indicates whether the icons which illustrate the user’s state (state icons) are displayed.

[Visual Basic,VBScript]
Property ShowIcons As Boolean
[C++]
HRESULT get_ShowIcons(VARIANT_BOOL* pVal);
HRESULT put_ShowIcons(VARIANT_BOOL newVal);
[IDL]
HRESULT [propget] ShowIcons([out, retval] VARIANT_BOOL *pVal);
HRESULT [propput] ShowIcons([in] VARIANT_BOOL newVal);

Remarks

This property can be set with an HTML <param> tag. The default value when creating a new list is True.


ShowLogonButton Property

The ShowLogonButton property indicates whether a logon prompt is displayed if the local user is not already logged on to the IM service provider.

[Visual Basic,VBScript]
Property ShowLogonButton as Boolean
[C++]
HRESULT get_ShowLogonButton(VARIANT_BOOL* pVal);
HRESULT put_ShowLogonButton(VARIANT_BOOL newVal);
[IDL]
HRESULT [propget] ShowLogonButton([out,retval] VARIANT_BOOL* pVal);
HRESULT [propput] ShowLogonButton([in] VARIANT_BOOL newVal);

Remarks

When this property is set to True, a logon prompt is placed near the center of the Contact View window.

This property can be set with an HTML <param> tag. The default value when creating a new list is False.


ShowSelectAlways Property

The ShowSelectAlways property indicates whether to continuously show the selection on the list.

[Visual Basic,VBScript]
Property ShowSelectAlways as Boolean
[C++]
HRESULT get_ShowSelectAlways (VARIANT_BOOL* pVal);
HRESULT put_ShowSelectAlways (VARIANT_BOOL newVal);
[IDL]
HRESULT [propget] ShowSelectAlways ([out,retval] VARIANT_BOOL* pVal);
HRESULT [propput] ShowSelectAlways ([in] VARIANT_BOOL newVal);

Remarks

This property can be set with an HTML <param> tag. The default value when creating a new list is False.


Window Property

The Window property returns the handle of the IM window.

[Visual Basic,VBScript]
Property Window as Long
read-only
[C++]
HRESULT get_Window(long* pVal);
[IDL]
HRESULT [propget] Window([out,retval] long* pVal);


Add Method

The Add method adds a contact or a list of contacts to the IM list.

[Visual Basic,VBScript]
Sub Add(ByVal vUser As Variant)
[C++]
HRESULT Add(VARIANT vUser);
[IDL]
HRESULT Add([in]VARIANT vUser);
vUser
A string containing the IM address of a single contact, a variant containing the IM reference for a single contact, or a safearray containing IM addresses or IM contact references for a list of contacts. Safearray contents can be mixed.

Remarks

If a list is set after users are added, the new list will overwrite the existing list with the added users.

When adding a list of contacts in a safearray to the IM list, the OnAddResult() event will fire for each IM address or IM contact reference added. The Add method itself will only return an error when something drastic occurs.


AddMenuItem Method

The AddMenuItem method adds a menu item to the context menu that is displayed when a selected contact is right-clicked.

[Visual Basic,VBScript]
Function AddMenuItem(
   ByVal bstrItem As String,
   ByVal pPosition As Long
) As Long
[C++]
HRESULT AddMenuItem(
   BSTR bstrItem,
   long lPosition,
   long* plCommand
);
[IDL]
HRESULT AddMenuItem(
   [in] BSTR bstrItem,
   [in, defaultvalue(-1)] long lPosition
   [out,retval] long* plCommand
);
bstrItem
The name of the item being added to the context menu. If bstrItem is set to an empty string (“ ”), a menu separator is inserted.
lPosition
The placement order of the command being added to the context menu. Setting the lPosition to –1 causes the new command to be added (appended) to the end of the context menu.
plCommand
A unique identifier for the command which is used to determine which menu item the user has selected in the DMSIMContactViewEvents::OnMenuSelect callback.

Remarks

Items added to the context menu with the AddMenuItem method are valid only for the next display of the context menu. The added items are removed when the list is no longer displayed. The context menu is rebuilt each time it is called according to the context in which it is displayed. This method should only be called in the DMSIMContactViewEvents::OnMenuRequest event.

For items that are menu separators, you do not need to save the plCommand, because it will not be used.


BlockSelected Method

The BlockSelected method adds the selected contact to the block list.

[Visual Basic,VBScript]
Sub BlockSelected()
[C++]
HRESULT BlockSelected();
[IDL]
HRESULT BlockSelected();

Remarks

A contact can only exist on either the Allow or the Block list, not on both simultaneously. Once a contact has been moved to an Allow or Block list, the contact will appear as such on each Contact list created.


EMailSelected Method

The EmailSelected method initiates an e-mail message to the selected contact on the IM list.

[Visual Basic,VBScript]
Sub EMailSelected()
[C++]
HRESULT EMailSelected();
[IDL]
HRESULT EMailSelected();

Remarks

EMailSelected uses a mailto: shell command to initiate the user’s default mail client to send an e-mail message if the contact’s e-mail address is available. If the selected contact does not have an e-mail address associated with it, a call to this method will fail and return E_INVALID_ARG.

Calling EMailSelected causes the DMSIMContactViewEvents::OnEMailContact event to fire. An application can override the default e-mail action by setting pfEnableDefault to False in DMSIMContactViewEvents::OnEMailContact.


IMSelected Method

The IMSelected method initiates an IM session with the selected contact on the IM list.

[Visual Basic,VBScript]
Sub IMSelected()
[C++]
HRESULT IMSelected();
[IDL]
HRESULT IMSelected();

Remarks

This method opens an instance of the MSIMMessageView control with the selected contact as a session member.

Calling IMSelected causes the DMSIMContactViewEvents::OnLaunchMessageUI event to fire. An application can override the default action by setting pfEnableDefault to False in DMSIMContactViewEvents::OnLaunchMessageUI.


InviteSelected Method

The InviteSelected method initiates an invitation to join NetMeeting to the selected contact on the Contact list.

[Visual Basic,VBScript]
Sub InviteSelected()
[C++]
HRESULT InviteSelected();
[IDL]
HRESULT InviteSelected();

Remarks

This method initiates an invitation to NetMeeting with the selected contact. Calling InviteSelected causes an instance of the MSIMMessageView control to open with the selected contact as a member. The invitation messages are displayed within this MSIMMessageView control.


Remove Method

The Remove method removes a contact or a list of contacts from the IM list.

[Visual Basic,VBScript]
Sub Remove(ByVal vUser As Variant)
[C++]
HRESULT Remove(VARIANT vUser);
[IDL]
HRESULT Remove([in] VARIANT vUser);
vUser
A string containing the IM address of a single contact, a variant containing the IM reference for a single contact, or a safearray containing IM addresses or IM contact references for a list of contacts. Safearray contents can be mixed.

Remarks

When removing a list of contacts in a safearray from the IM list, the OnRemoveResult() event will fire for each IM address or IM contact reference removed. The Remove method itself will only return an error when something drastic occurs.


UnblockSelected Method

The UnblockSelected method removes the selected contact from the block list and adds the contact to the Allow list.

[Visual Basic,VBScript]
Sub UnblockSelected()
[C++]
HRESULT UnblockSelected();
[IDL]
HRESULT UnblockSelected();

Remarks

A contact can only exist on either the Allow or the Block list, not on both simultaneously. Once a contact has been moved to an Allow or Block list, the contact will appear as such on each Contact list created.


IMSIMHost Interface

The IMSIMHost Interface is the application interface for accessing Instant Messaging (IM) services and provides additional services used by IM solutions.

IID
7B8E28EB-1A74-4970-8AB4-4EA9DB048006
Extends
IDispatch

Member Summary

Properties

Name | Type | Description
Profiles (Read-Only) | [Visual Basic,VBScript] Object [C++,IDL] IDispatch** | Reserved for future use.

Methods

Name | Description
CreateContext | Returns an interface pointer to IIMService.
CreateProfile | Reserved for future use.
HostWindow | Creates a child window that hosts a specified Microsoft® ActiveX® control.
HostWindowEx | Creates a child window that hosts a specified ActiveX control.
PopupMessage | Reserved for future use.
ShowOptions | Displays the IM Host property pages.


Profiles Property

Reserved for future use.

[Visual Basic,VBScript]
Property Profiles As Object
read-only
[C++]
HRESULT get_Profiles(IDispatch** pVal)
[IDL]
HRESULT [propget] Profiles([out, retval] IDispatch** pVal)


CreateContext Method

The CreateContext method returns an interface pointer to IIMService.

[Visual Basic,VBScript]
Function CreateContext(
   ByVal Profile As Variant,
   ByVal Flags as Variant
) As Object
[C++]
HRESULT CreateContext(
   VARIANT Profile,
   VARIANT Flags,
   IDispatch** ppInterface
);
[IDL]
HRESULT CreateContext(
   [in] VARIANT Profile,
   [in] VARIANT Flags,
   [out, retval] IDispatch **ppInterface
);
Profile
Must be set to Default.
Flags
Must be set to 0 (zero).

Example

[Visual Basic]
Public WithEvents oIMServ As MSIMCliSDKLib.MSIMService
Public WithEvents oIMApp As MSIMCliSDKLib.MSIMHost

Set oIMApp = CreateObject("MSExchangeIM.MSIMHost")
Set oIMServ = oIMApp.CreateContext("Default", 0)

'logon to the IM service, providing no parameter will prompt the user for credentials
oIMServ.Logon


CreateProfile Method

Reserved for future use.

[Visual Basic,VBScript]
Function CreateProfile(ByVal bstrProfile As String) As Object
[C++]
HRESULT CreateProfile(
   BSTR bstrProfile,
   IDispatch** ppDispatch
);
[IDL]
HRESULT CreateProfile(
   [in] BSTR bstrProfile,
   [out, retval] IDispatch **ppDispatch
);


HostWindow Method

The HostWindow method creates a child window that hosts a specified ActiveX control.

[Visual Basic,VBScript]
Function HostWindow(
   ByVal bstrControl As String
   lStyle As Long,
   fShowOnTaskbar As Boolean
) As Object
[C++]
HRESULT HostWindow(
   BSTR bstrControl,
   long lStyle,
   VARIANT_BOOL fShowOnTaskbar,
   IDispatch** ppMSIMWnd
);
[IDL]
HRESULT HostWindow(
   [in] BSTR bstrControl,
   [in] long lStyle,
   [in] VARIANT_BOOL fShowOnTaskbar,
   [out, retval] IDispatch **ppMSIMWnd
);
bstrControl
A string used to create the control. The string must be a ProgID, a CLSID, a URL, a reference to an active document, or a fragment of HTML. If the string is an HTML fragment, it must be preceded by “MSHTML:” to designate the fragment as an MSHTML stream.
lStyle
A member of the MSIMWND_STYLES enumeration the style of window that should be used.
fShowOnTaskbar
A flag that determines whether the window displays on the taskbar when its application is minimized.


HostWindowEx Method

The HostWindowEx method creates a child window that hosts a specified ActiveX control.

[Visual Basic,VBScript]
Function HostWindowEx(
   bstrControl As String,
   lStyle As Long,
   lExStyle As Long,
   pStream As IStream,
   ppMSIMWindow As IMSIMWindow,
   ppUnk As IUnknown,
   iidAdvise As REFIID,
   punkSink As IUnknown
)
[C++]
HRESULT HostWindowEx(
   BSTR bstrControl,
   long lStyle,
   long lExStyle,
   IStream* pStream,
   IMSIMWindow** ppMSIMWindow,
   IUnknown** ppUnk,
   REFIID iidAdvise,
   IUnknown* punkSink
);
[IDL]
HRESULT HostWindowEx(
   [in] BSTR bstrControl,
   [in] long lStyle,
   [in] long lExStyle,
   [in] IStream* pStream,
   [out] IMSIMWindow** ppMSIMWindow,
   [out] IUnknown** ppUnk,
   [in] REFIID iidAdvise,
   [in] IUnknown* punkSink
);
bstrControl
A string used to create the control. The string must be a ProgID, a CLSID, a URL, a reference to an active document, or a fragment of HTML. If the string is an HTML fragment, it must be preceded by “MSHTML:” to designate the fragment as an MSHTML stream.
lStyle
Corresponds to the dwStyle parameter in the Microsoft® Windows® CreateWindowEx function. For additional information on this parameter, see the CreateWindowEx function in the MSDN® Library.
lExSytle
Corresponds to the dwExStyle parameter in the Windows CreateWindowEx function. For additional information on this parameter, see the CreateWindowEx function in the MSDN Library.


PopupMessage Method

Reserved for future use.

[Visual Basic,VBScript]
Function PopupMessage(
   ByVal bstrMessage As String,
   [ByVal nTimeout As Long],
   [fClick As Boolean]
) As Long
[C++]
HRESULT PopupMessage(
   BSTR bstrMessage,
   long nTimeout,
   VARIANT_BOOL fClick,
   long* plCookie
);
[IDL]
HRESULT PopupMessage(
   [in] BSTR bstrMessage,
   [in, optional, defaultvalue(10)] long nTimeout,
   [in, optional,defaultvalue(0)] VARIANT_BOOL fClick,
   [out, retval, defaultvalue(0)] long* plCookie
);


ShowOptions Method

The ShowOptions method displays the IM Host property pages.

[Visual Basic,VBScript]
Sub ShowOptions()
[C++]
HRESULT ShowOptions();
[IDL]
HRESULT ShowOptions();


IMSIMMessageView Interface

The IMSIMMessageView interface defines properties and methods used to manage an existing MSIMMessageView object.

IID
053A4F4E-B931-4602-8C73-ABD3040558F2
Extends
_IUseIMBase

Member Summary

Properties

Name | Type | Description
Appearance | [Visual Basic,VBScript] Short [C++,IDL] short | Reserved for future use.
AvailableList | [Visual Basic,VBScript] Variant [C++,IDL] VARIANT | Sets and retrieves the list that is displayed as the Available To Join list for the session.
HideStatus | [Visual Basic,VBScript] Boolean [C++,IDL] VARIANT_BOOL | Reserved for future use.
MessageHistory (Read-Only) | [Visual Basic,VBScript] String [C++,IDL] BSTR | Returns the contents of the Conversation History pane.
MessageText | [Visual Basic,VBScript] String [C++,IDL] BSTR | Sets and retrieves the contents of the Outgoing Message pane, but does not send the text.
ShowAvailable | [Visual Basic,VBScript] Boolean [C++,IDL] VARIANT_BOOL | Reserved for future use.
ShowEdit | [Visual Basic,VBScript] Boolean [C++,IDL] VARIANT_BOOL | Reserved for future use.
ShowMembers | [Visual Basic,VBScript] Boolean [C++,IDL] VARIANT_BOOL | Reserved for future use.
ShowMessageHistory | [Visual Basic,VBScript] Boolean [C++,IDL] VARIANT_BOOL | Reserved for future use.
ShowParticipants | [Visual Basic,VBScript] Boolean [C++,IDL] VARIANT_BOOL | Reserved for future use.
SourceURL | [Visual Basic,VBScript] String [C++,IDL] BSTR | Sets the Universal Resource Identifier (URI) of the HTML page to be loaded.
StatusText | [Visual Basic,VBScript] String [C++,IDL] BSTR | Sets and retrieves the contents of the Status Message pane.
Window (Read-Only) | [Visual Basic,VBScript] Long [C++,IDL] long | Returns the handle of the Instant Messaging (IM) window.

Methods

Name | Description
AddToAvailable | Adds a contact to the Available To Join list by implementing the IMSIMContactView::Add method.
EndSession | Removes the local user from the current IM session.
Invite | Associates an existing IMSession to the Message View or invites a contact to the current IM session.
InviteNetMeeting | Invites all the members of an IM session to a Microsoft® NetMeeting® session.
NetMeetingInvite | Forwards the DIMServiceEvents::OnNetMeetingInviteReceived event to a new message window and requests that the window manage the session.
RemoveFromAvailable | Removes a contact from the Available To Join list by invoking the IMSIMContactView::Remove method.


Appearance Property

Reserved for future use.

[Visual Basic,VBScript]
Property Appearance As Short
[C++]
HRESULT get_Appearance(short* pappearance);
HRESULT put_Appearance(short appearance);
[IDL]
HRESULT [propget] Appearance([out, retval] short* pappearance);
HRESULT [propput] Appearance([in] short appearance);


AvailableList Property

The AvailableList property sets and retrieves the list that is displayed as the Available to Join list for the session.

[Visual Basic,VBScript]
Property AvailableList As Variant
[C++]
HRESULT get_AvaliableList(VARIANT* pVal);
HRESULT put_AvaliableList(VARIANT newVal);
[IDL]
HRESULT [propget] AvaliableList([out, retval] VARIANT *pVal);
HRESULT [propput] AvaliableList([in] VARIANT newVal);


HideStatus Property

Reserved for future use.

[Visual Basic,VBScript]
Property HideStatus As Boolean
[C++]
HRESULT get_HideStatus(VARIANT_BOOL* pVal);
HRESULT put_HideStatus(VARIANT_BOOL newVal);
[IDL]
HRESULT [propget] HideStatus([out, retval] VARIANT_BOOL* pVal);
HRESULT [propput] HideStatus([in] VARIANT_BOOL newVal);


MessageHistory Property

The MessageHistory property returns the contents of the Conversation History pane.

[Visual Basic,VBScript]
Property MessageHistory As String
read-only
[C++]
HRESULT get_MessageHistory(BSTR* pVal);
[IDL]
HRESULT [propget] MessageHistory([out, retval] BSTR *pVal);


MessageText Property

The MessageText property sets and retrieves the contents of the Outgoing Message pane, but does not send the text.

[Visual Basic,VBScript]
Property MessageText As String
[C++]
HRESULT get_MessageText(BSTR* pVal);
HRESULT put_MessageText(BSTR newVal);
[IDL]
HRESULT [propget] MessageText([out, retval] BSTR *pVal);
HRESULT [propput] MessageText([in] BSTR newVal);


ShowAvailable Property

Reserved for future use.

[Visual Basic,VBScript]
Property ShowAvailable As Boolean
[C++]
HRESULT get_ShowAvaliable(VARIANT_BOOL* pVal);
HRESULT put_ShowAvaliable(VARIANT_BOOL newVal);
[IDL]
HRESULT [propget] ShowAvaliable([out, retval] VARIANT_BOOL *pVal);
HRESULT [propput] ShowAvaliable([in] VARIANT_BOOL newVal);


ShowEdit Property

Reserved for future use.

[Visual Basic,VBScript]
Property ShowEdit As Boolean
[C++]
HRESULT get_ShowEdit(VARIANT_BOOL* pVal);
HRESULT put_ShowEdit(VARIANT_BOOL newVal);
[IDL]
HRESULT [propget] ShowEdit([out, retval] VARIANT_BOOL *pVal);
HRESULT [propput] ShowEdit([in] VARIANT_BOOL newVal);


ShowMembers Property

Reserved for future use.

[Visual Basic,VBScript]
Property ShowMembers As Boolean
[C++]
HRESULT get_ShowMembers(VARIANT_BOOL* pVal);
HRESULT put_ShowMembers(VARIANT_BOOL newVal);
[IDL]
HRESULT [propget] ShowMembers([out, retval] VARIANT_BOOL *pVal);
HRESULT [propput] ShowMembers([in] VARIANT_BOOL newVal);


ShowMessageHistory Property

Reserved for future use.

[Visual Basic,VBScript]
Property ShowMessageHistory As Boolean
[C++]
HRESULT get_ShowMessageHistory(VARIANT_BOOL* pVal);
HRESULT put_ShowMessageHistory(VARIANT_BOOL newVal);
[IDL]
HRESULT [propget] ShowMessageHistory([out, retval] VARIANT_BOOL *pVal);
HRESULT [propput] ShowMessageHistory([in] VARIANT_BOOL newVal);


ShowParticipants Property

Reserved for future use.

[Visual Basic,VBScript]
Property ShowParticipants As Boolean
[C++]
HRESULT get_ShowParticipants(VARIANT_BOOL* pVal);
HRESULT put_ShowParticipants(VARIANT_BOOL newVal);
[IDL]
HRESULT [propget] ShowParticipants([out, retval] VARIANT_BOOL *pVal);
HRESULT [propput] ShowParticipants([in] VARIANT_BOOL newVal);


SourceURL Property

The SourceURL property sets the Universal Resource Identifier (URI) of the HTML page to be loaded.

[Visual Basic,VBScript]
Property SourceURL as String
[C++]
HRESULT get_SourceURL(BSTR* pVal);
HRESULT put_SourceURL(BSTR newVal);
[IDL]
HRESULT [propget] SourceURL([out,retval] BSTR *pVal);
HRESULT [propput] SourceURL([in] BSTR newVal);

Remarks

If a relative path is used in the URL, it will be evaluated based on the location of the msimcntl.dll file.

This property must be set prior to initializing the control. The control will not update if the property is set after it has been loaded.

The URL must be an absolute path to the source file.

When SourceURL is used to load a custom HTML page, the custom HTML page must include elements with defined IDs and types that the control will use at run time. These elements are outlined below.

Example

<object
   classid=clsid:528B6917-4DED-43F1-B56C-35A1519129CA
   id=message>
   <param name=”Service” value=0>
   <param name=”SourceURL” value=”http://yourserver/IM_message.htm”>
</object>

HTML Elements to Use in the Custom User Interface

Participants List Object

Element type: object

ID: ParticipantsList

This object is the IM Contact View control that is used to display the contacts that are currently active and participating in the session associated with this message instance.

This object is optional, but if it is not included, an alternate method must be provided by the custom HTML code to add users to a session.

MSIMContactView properties may be included in the object tag. The page may use the MSIMContactView object model to further control this element.

Example
<object
   classid=CLSID:B06EDBC7-287D-405C-A899-9C7F8358EF26
   id=”ParticipantsList”>
</object>
Available List Object

Element type: object

ID: AvailableList

This object is the MSIMContactView control and is used to display the contacts that are currently in the available list as specified with MessageView.AvailableList or the “$$Messenger\Contact” list if none is specified.

This object is optional, however, it is a useful alternative to using the Contact View control to provide a custom user interface for adding users into a session.

MSIMContactView properties may be included in the object tag. The page may use the MSIMContactView object model to further control this element.

Example
<object
   classid= CLSID:B06EDBC7-287D-405C-A899-9C7F8358EF26
   id=”AvailableList”>
</object>
Message History iFrame

Element type: iFrame

ID: history

This iFrame is used to display the ongoing message conversation.

This object is optional, and can be omitted if the message view is to be used only for sending, since no incoming messages would be displayed.

Example
<IFRAME ID=”history” SRC=””></IFRAME>
Message Send Text textarea

Element type: textarea

ID: chat

This textarea is the input area for the text that is sent when the send button is clicked or activated. The textarea.value is sent, including its current formatting, when the send action is initiated.

This object is optional and can be omitted if the message view is for displaying incoming messages only, such as a notification message.

This element should be disabled by default to prevent it from being active before the Message View control has created a session.

This element is the buffer for the outgoing message. If desired, this element can be hidden, and another input element (such as RTFEdit control) can be used for editing, and the contents of that element copied into the SentText textarea by script prior to sending the message. This may allow for more flexibility in the outgoing text edit area.

Example
<TEXTAREA ID=”chat” DISABLED=TRUE></TEXTAREA>
Send Button

Element type: any element with an OnClick event

ID: btnSend

The send element is used to initiate the sending of the chat textarea contents to the message session participants.

This object is optional, but without a send button, no messages can be sent.

This element can be any IHTMLElement that supports the OnClick event including INPUT TYPE=BUTTON, DIV, SPAN, A, and so forth.

The Message View control captures the “enter” keystroke as the keyboard accelerator to initiate sending text, which cannot be overridden by the UI page.

Example
<SPAN ID=btnSend>Send</SPAN>

or

<INPUT ID=”btnSend” TYPE=”button” Value=”Send”>
Status

Element type: div or span

ID: status

The status element is used by the control to display incoming status messages including the “isTyping” message.

This object is optional, and is currently only used to display the “isTyping” message.

Example
<DIV id=”status”></DIV>

Example

The following is an example of an HTML page containing all Message View elements.

<HTML>
<HEAD>
<TITLE>Instant Messaging</TITLE>
</HEAD>
<BODY>
<OBJECT classid=CLSID:B06EDBC7-287D-405C-A899-9C7F8358EF26
        codeType=application/x-oleobject
        id=ParticipantsList style=”border:thin inset”
        height=150px width=150px>
</OBJECT>

<OBJECT classid=CLSID:B06EDBC7-287D-405C-A899-9C7F8358EF26
        codeType=application/x-oleobject
        id=AvailableList style=”border:thin inset”
        height=150px width=150px>
</OBJECT>
<br>
<IFRAME style=”border:thin inset” ID=”history” SRC=””></IFRAME>
<br>
<TEXTAREA ID=”chat” style=”FONT: 10pt Arial” cols=80 rows=5>
&lttype your message here&gt
</TEXTAREA>
<br>
<INPUT Type=”button” ID=btnSend Value=”Send”>
<DIV id=”status”></DIV>
</BODY>
</HTML>
© 2000-2001 Microsoft Corporation. All rights reserved.


StatusText Property

The StatusText property sets and retrieves the contents of the Status Message pane.

[Visual Basic,VBScript]
Property StatusText As String
[C++]
HRESULT get_StatusText(BSTR* pVal);
HRESULT put_StatusText(BSTR newVal);
[IDL]
HRESULT [propget] StatusText([out, retval] BSTR *pVal);
HRESULT [propput] StatusText([in] BSTR newVal);

Remarks

The StatusText string is displayed in the Status Message pane until a new status is set by this interface or received from other session participants.


Window Property

The Window property returns the handle of the IM window.

[Visual Basic,VBScript]
Property Window As Long
read-only
[C++]
HRESULT get_Window(long* phwnd);
[IDL]
HRESULT [propget] Window(long* phwnd);


AddToAvailable Method

The AddToAvailable method adds a contact to the Available To Join list by implementing the IMSIMContactView::Add method.

[Visual Basic,VBScript]
Sub AddToAvaliable(ByVal varContact As Variant)
[C++]
HRESULT AddToAvaliable(VARIANT varContact);
[IDL]
HRESULT AddToAvaliable([in]VARIANT varContact);
varContact
A string containing the IM address of a single contact, a variant containing the IM reference for a single contact, or a safearray containing either all IM addresses or all IM contact references for a list of contacts. Safearray contents cannot be mixed.


EndSession Method

The EndSession method removes the local user from the current IM session.

[Visual Basic,VBScript]
Sub EndSession()
[C++]
HRESULT EndSession();
[IDL]
HRESULT EndSession();


Invite Method

The Invite method associates an existing IMSession to the Message View or invites a contact to the current IM session.

[Visual Basic,VBScript]
Sub Invite(ByVal varContact As Variant)
[C++]
HRESULT Invite(VARIANT varContact);
[IDL]
HRESULT Invite([in]VARIANT varContact);
varContact
A string containing the IM address of a single contact or a variant containing the IM reference for a single contact or a reference to an IMSession.


InviteNetMeeting Method

The InviteNetMeeting method invites all the members of an IM session to a NetMeeting session.

[Visual Basic,VBScript]
Sub InviteNetMeeting()
[C++]
HRESULT InviteNetMeeting();
[IDL]
HRESULT InviteNetMeeting();


NetMeetingInvite Method

The NetMeetingInvite method forwards the DIMServiceEvents::OnNetMeetingInviteReceived event to a new message window and requests that the window manage the session.

[Visual Basic,VBScript]
Sub NetMeetingInvite(
   pIMSession As Object
   pContact As Object
   lInviteCookie As Long
)
[C++]
HRESULT NetMeetingInvite(
   IDispatch* pIMSession,
   IDispatch* pContact,
   long lInviteCookie
);
[IDL]
HRESULT NetMeetingInvite(
   [in] IDispatch* pIMSession,
   [in] IDispatch* pContact,
   [in] long lInviteCookie
);
lInviteCookie
A numeric identifier used to correlate matching send and receive events. This cookie is passed through the OnNetMeetingInviteReceived notification.


RemoveFromAvailable Method

The RemoveFromAvailable method removes a contact from the Available To Join list by invoking the IMSIMContactView::Remove method.

[Visual Basic,VBScript]
Sub RemoveFromAvailable(varContact as Variant);
[C++]
HRESULT RemoveFromAvailable(VARIANT varContact);
[IDL]
HRESULT RemoveFromAvailable([in] VARIANT varContact);
varContact
A string containing the IM address of a single contact, a variant containing the IM reference for a single contact, or a safearray containing either all IM addresses or all IM contact references for a list of contacts. Safearray contents cannot be mixed.


IMSIMWindow Interface

The IMSIMWindow interface defines properties and methods used to control a Microsoft® ActiveX® hosting window.

IID
B3B674C2-844B-48F8-8EAA-A2C2E3BC43C7
Extends
IDispatch

Member Summary

Properties

Name | Type | Description
HasFocus (Read-Only) | [Visual Basic,VBScript] Boolean [C++,IDL] VARIANT_BOOL | Indicates whether the window currently has focus.
IsVisible (Read-Only) | [Visual Basic,VBScript] Boolean [C++,IDL] VARIANT_BOOL | Indicates whether the window is currently visible to the user.
Object (Read-Only) | [Visual Basic,VBScript] Object [C++,IDL] IDispatch** | Returns a pointer to the ActiveX control posted in the window.
Title | [Visual Basic,VBScript] String [C++,IDL] BSTR | Returns and sets the window title.
TopMost | [Visual Basic,VBScript] Boolean [C++,IDL] VARIANT_BOOL | Indicates whether the window is always the top window.
Window | [Visual Basic,VBScript] Long [C++,IDL] long | Returns the handle of the window.

Methods

Name | Description
Close | Closes the client window.
Focus | Attempts to set the focus on the window.
GetPosition | Returns the X and Y position and the width and height of the window.
Hide | Posts the window an SW_HIDE command, keeping the window in the Z order but not displaying it.
Move | Moves the window and sets its size in pixels.
Show | Posts the window an SW_SHOW message.


HasFocus Property

The HasFocus property indicates whether the window currently has focus.

[Visual Basic,VBScript]
Property HasFocus As Boolean
read-only
[C++]
HRESULT get_HasFocus(VARIANT_BOOL* pVal);
[IDL]
HRESULT [propget] HasFocus([out, retval] VARIANT_BOOL* pVal);


IsVisible Property

The IsVisible property indicates whether the window is currently visible to the user.

[Visual Basic,VBScript]
Property IsVisible As Boolean
read-only
[C++]
HRESULT get_IsVisible(VARIANT_BOOL* pVal);
[IDL]
HRESULT [propget] IsVisible([out, retval] VARIANT_BOOL* pVal);


Object Property

The Object property returns a pointer to the ActiveX control posted in the window.

[Visual Basic,VBScript]
Property Object As Object
read-only
[C++]
HRESULT get_Object(IDispatch** ppDisp);
[IDL]
HRESULT [propget] Object([out, retval] IDispatch **ppDisp);


Title Property

The Title property contains the window title.

[Visual Basic,VBScript]
Property Title As String
[C++]
HRESULT get_Title(BSTR* pVal);
HRESULT put_Title(BSTR newVal);
[IDL]
HRESULT [propget] Title(BSTR* pVal);
HRESULT [propput] Title(BSTR newVal);


TopMost Property

The TopMost property indicates whether the window is always the top window.

[Visual Basic,VBScript]
Property TopMost As Boolean
[C++]
HRESULT get_TopMost (VARIANT_BOOL* pVal);
HRESULT put_TopMost (VARIANT_BOOL newVal);
[IDL]
HRESULT [propget] TopMost([out, retval] VARIANT_BOOL *pVal);
HRESULT [propput] TopMost([in] VARIANT_BOOL newVal);


Window Property

The Window property returns the handle of the window.

[Visual Basic,VBScript]
Property Window As Boolean
read-only
[C++]
HRESULT get_Window (long* pVal);
[IDL]
HRESULT [propget] Window([out, retval] long *pVal);


Close Method

The Close method closes the client window.

[Visual Basic,VBScript]
Sub Close()
[C++]
HRESULT Close();
[IDL]
HRESULT Close();


Focus Method

The Focus method attempts to set the focus on the window.

[Visual Basic,VBScript]
Sub Focus()
[C++]
HRESULT Focus();
[IDL]
HRESULT Focus();

Remarks

If the focus method fails to set the focus on the window, it flashes the window.


GetPosition Method

The GetPosition method returns the X and Y position and the width and height of the window.

[Visual Basic,VBScript]
Sub GetPosition(
   pvarX As Variant,
   pvarY As Variant,
   pvarWidth As Variant,
   pvarHeight As Variant
)
[C++]
HRESULT GetPosition(
   VARIANT* pvarX,
   VARIANT* pvarY,
   VARIANT* pvarWidth,
   VARIANT* pvarHeight
);
[IDL]
HRESULT GetPosition(
   [out] VARIANT* pvarX,
   [out] VARIANT* pvarY,
   [out] VARIANT* pvarWidth,
   [out] VARIANT* pvarHeight
);


Hide Method

The Hide method posts the window an SW_HIDE command, keeping the window in the Z order but not displaying it.

[Visual Basic,VBScript]
Sub Hide()
[C++]
HRESULT Hide();
[IDL]
HRESULT Hide();


Move Method

The Move method moves the window and sets its size in pixels.

[Visual Basic,VBScript]
Sub Move(
   ByVal nX As Long,
   ByVal nY As Long,
   ByVal nWidth As Long,
   ByVal nHeight As Long
)
[C++]
HRESULT Move(
   long nX,
   long nY,
   long nWidth,
   long nHeight
);
[IDL]
HRESULT Move(
   [in] long nX,
   [in] long nY,
   [in] long nWidth,
   [in] long nHeight
);
nX
The new x coordinate for the window.
nY
The new y coordinate for the window.
nWidth
The new width for the window.
nHeight
The new height for the window.


Show Method

The Show method posts the window an SW_SHOW message.

[Visual Basic,VBScript]
Sub Show()
[C++]
HRESULT Show();
[IDL]
HRESULT Show();


_IUseIMBase Interface

The _IUseIMBase interface defines properties and methods used to configure and set up Instant Messaging (IM) service from the control. This interface is inherited by the IMSIMContactView and IMSIMMessageView interfaces, and is accessible only by creating MSIMContactView and MSIMMessageView objects.

IID
9D921DA0-DFE1-45AE-9EB6-E50A2770A57E
Extends
IDispatch

Member Summary

Properties

Name | Type | Description
AutoLogon | [Visual Basic,VBScript] Boolean [C++,IDL] VARIANT_BOOL | Indicates that the object should attempt to log on.
HasService (Read-Only) | [Visual Basic,VBScript] Boolean [C++,IDL] VARIANT_BOOL | Indicates whether the object is connected to an IM service provider.
LoggedOn (Read-Only) | [Visual Basic,VBScript] Boolean [C++,IDL] VARIANT_BOOL | Indicates whether the local user is logged on.
Service | [Visual Basic,VBScript] Short [C++,IDL] short | Returns and sets the service to be used by the control.

Methods

Name | Description
GetLocalState | Indicates the user’s current state.
Logoff | Logs a local user off of IM.
Logon | Logs a local user on to IM.
SetLocalState | Sets the local user’s current state.
SetService | Gives an object a pointer to a currently active IM service.


AutoLogon Property

The AutoLogon property indicates that the object should attempt to log on.

[Visual Basic,VBScript]
Property AutoLogon As Boolean
[C++]
HRESULT get_AutoLogon(VARIANT_BOOL* pVal);
HRESULT put_AutoLogon(VARIANT_BOOL newVal);
[IDL]
HRESULT [propget] AutoLogon([out, retval] VARIANT_BOOL *pVal);
HRESULT [propput] AutoLogon([in] VARIANT_BOOL newVal);

Remarks

If set to True, the AutoLogon property attempts to log a local user on to the IM service when the control is loaded. The local user will be prompted if credentials are needed.

This property can be set using an HTML <param> tag.


HasService Property

The HasService property indicates whether the object is connected to an IM service provider.

[Visual Basic,VBScript]
Property HasService As Boolean
[C++]
HRESULT get_HasService(VARIANT_BOOL* pVal);
[IDL]
HRESULT [propget] HasService([out, retval] VARIANT_BOOL *pval);

Remarks

If this property returns False, the service can be set with the _IUseIMBase.Service property or by calling the _IUseIMBase::SetService method. This property will return False if the service provider has shut down.


LoggedOn Property

The LoggedOn property indicates whether the local user is logged on.

[Visual Basic,VBScript]
Property LoggedOn As Boolean
[C++]
HRESULT get_LoggedOn(VARIANT_BOOL* pVal);
[IDL]
HRESULT [propget] LoggedOn([out, retval] VARIANT_BOOL *pVal);

Remarks

If this property returns False, call the _IUseIMBase::Logon method to log the user on to IM.


Service Property

The Service property returns and sets the service to be used by the control.

[Visual Basic,VBScript]
Property Service As Short
[C++]
HRESULT get_Service(short* pVal);
HRESULT put_Service(short newVal);
[IDL]
HRESULT [propget] Service([out], retval] short *pval);
HRESULT [propput] Service([in] short newVal);

Remarks

Setting this property with a value of 0 sets all registered IM service providers. Setting this property with a value of 1 sets the service to the Exchange IM service provider. Currently the Exchange IM service is the only registered IM service provider, thus 0 and 1 produce the same result.

This property can be set using an HTML <param> tag.

See Also

MSIM_PROVIDER Enumeration

© 2000-2001 Microsoft Corporation. All rights reserved.


GetLocalState Method

The GetLocalState method indicates the local user’s current state.

[Visual Basic,VBScript]
Function GetLocalState(
   pvarState As Variant,
   [pvarDescription As Variant,]
   [pvarData As Variant]
)
[C++]
HRESULT GetLocalState(
   VARIANT* pvarState,
   VARIANT* pvarDescription,
   VARIANT* pvarData
);
[IDL]
HRESULT GetLocalState(
   [out] VARIANT *pvarState,
   [out, optional] VARIANT *pvarDescription,
   [out, optional] VARIANT *pvarData
);
pvarState
A member of the IM_STATE enumeration.
pvarDescription
A description of the state generated by the host.
pvarData
Reserved for future use.


Logoff Method

The Logoff method logs a local user off of IM.

[Visual Basic,VBScript]
Sub Logoff()
[C++]
HRESULT Logoff();
[IDL]
HRESULT Logoff();

Remarks

This method sets the local state to Offline. If IMSIMContactView::ShowLogonButton is set to True, the contact list will be replaced with a logon prompt. A call to the Logoff method will fail if the network connectivity fails or if the user is already logged off.


Logon Method

The Logon method logs a local user on to IM.

[Visual Basic,VBScript]
Sub Logon(
   [bstrAddress As String],
   [bstrName As String],
   [bstrPassword As String],
   [bstrDomain As String]
)
[C++]
HRESULT Logon(
   BSTR bstrAddress,
   BSTR bstrName,
   BSTR bstrPassword,
   BSTR bstrDomain
);
[IDL]
HRESULT Logon(
   [in, ptr, defaultvalue(“”)] BSTR bstrAddress,
   [in, ptr, defaultvalue(“”)] BSTR bstrName,
   [in, ptr, defaultvalue(“”)] BSTR bstrPassword,
   [in, ptr, defaultvalue(“”)] BSTR bstrDomain
);
bstrAddress
The IM address of the local user to be logged on.
bstrName
The logon name of the local user.
bstrPassword
The password for the local user.
bstrDomain
The domain of the local user.

Remarks

If an IM address is passed as a parameter, the system will attempt to log the user on to the IM service. The Exchange IM service only uses IM addresses, and performs system authentication methods to log on to the service. Other IM services can use the other parameters.


SetLocalState Method

The SetLocalState method sets the user’s current state.

[Visual Basic,VBScript]
Sub SetLocalState(
   lState As Long,
   [varDescription As Variant],
   [varData As Variant]
)
[C++]
HRESULT SetLocalState(
   long lState,
   VARIANT varDescription,
   VARIANT varData
);
[IDL]
HRESULT SetLocalState(
   [in] long lState,
   [in, optional] VARIANT varDescription,
   [in, optional] VARIANT varData
);
lState
One of the following members of the IM_STATE enumeration: IM_STATE_UNKNOWN, IM_STATE_ONLINE, IM_STATE_INVISIBLE, IM_STATE_BUSY, IM_STATE_BE_RIGHT_BACK, IM_STATE_AWAY, IM_STATE_ON_THE_PHONE, IM_STATE_OUT_TO_LUNCH.
varDescription
Reserved for future use.
varData
Reserved for future use.


SetService Method

The SetService method gives an object a pointer to a currently active IM service.

[Visual Basic,VBScript]
Sub SetService(
   pObject As Unknown,
   pApp As Unknown
)
[C++]
HRESULT SetService(
   IDispatch* pObject,
   IDispatch* pApp
);
[IDL]
HRESULT SetService(
   [in] IDispatch *pObject
   [in, defaultvalue(0)] IDispatch *pApp
);
pObject
A pointer to a Service object.
pApp
A pointer to a Host object. This parameter can also be null.

Remarks

This method is used to allow applications that have already created Service and/or Host objects to make the controls use these existing objects instead of creating new ones.


DISPID Values

The following table lists Instant Messaging Service (IM) DISPIDs and their associated values.

DISPID | Value
MSIM_DISPID_ONLOGONRESULT | 0x0E00
MSIM_DISPID_ONLOGOFF | 0x0E01
MSIM_DISPID_ONLISTADDRESULT | 0x0E02
MSIM_DISPID_ONLISTREMOVERESULT | 0x0E03
MSIM_DISPID_ONFRIENDLYNAMECHANGERESULT | 0x0E04
MSIM_DISPID_ONCONTACTSTATECHANGED | 0x0E05
MSIM_DISPID_ONTEXTRECEIVED | 0x0E06
MSIM_DISPID_ONLOCALFRIENDLYNAMECHANGERESULT | 0x0E07
MSIM_DISPID_ONLOCALSTATECHANGERESULT | 0x0E08
MSIM_DISPID_ONSENDRESULT | 0x0E09
MSIM_DISPID_ONFINDRESULT | 0x0E0A
MSIM_DISPID_ONSESSIONSTATECHANGE | 0x0E0B
MSIM_DISPID_ONNEWSESSIONMEMBER | 0x0E0C
MSIM_DISPID_ONSESSIONMEMBERLEAVE | 0x0E0D
MSIM_DISPID_ONNEWSESSIONREQUEST | 0x0E0F
MSIM_DISPID_ONINVITECONTACT | 0x0E10
MSIM_DISPID_ONAPPSHUTDOWN | 0x0E12
MSIM_DISPID_ON_NM_INVITERECEIVED | 0x0E13
MSIM_DISPID_ON_NM_ACCEPTED | 0x0E14
MSIM_DISPID_ON_NM_CANCELLED | 0x0E15
MSIMWND_DISPID_ONMOVE | 0x00E0
MSIMWND_DISPID_ONCLOSE | 0x00E1
MSIMWND_DISPID_ONRESIZE | 0x00E2
MSIMWND_DISPID_ONSHOW | 0x00E3
MSIMWND_DISPID_ONFOCUS | 0x00E4
MSIMHOSTEVENTS_DISPID_ONDOUBLECLICK | 0xD
MSIMHOSTEVENTS_DISPID_ONSHUTDOWN | 0xE
MSIMHOSTEVENTS_DISPID_ONCLICKUSERNOTIFY | 0xF

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Conference Technology Provider

The following sections contain reference information to use when developing a Conference Technology Provider for Microsoft® Exchange 2000 Server.

Conference Management Service lists the interfaces, methods, and properties for the Conference Management Service.

Conference Technology Provider Service lists the interfaces, methods, and properties for the Conference Technology Provider Service.

CMS Administration Object lists the interfaces, methods, and properties for the CMS Administration object.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Conference Management Service

The Conference Management Service, a Windows 2000 service, implements the ConferenceManager object. The coclass definition follows:

coclass ConferenceManager
{
  [default] interface IConferenceLocator;
  interface IConferenceManager;
};

The default interface, IConferenceLocator, is used by the meeting access page (ASP script) to obtain information about a meeting and direct the client browser to the conference. A CTP uses the IConferenceManager interface directly.


IConferenceLocator

This automation interface is used by the client meeting’s ASP scripts or custom applications to direct a client browser to a conference. All methods are synchronous with respect to processing within the CMS.

Property values accessed by the IConferenceProfile:UserProperties method returned from this interface are defined as read-only.

Methods

The IConferenceLocator interface contains the following methods:

IConferenceLocator::GetProfilesByTime

IConferenceLocator::GetProviderExtension

IConferenceLocator::ConferenceJoinRequest

IConferenceLocator::ConferenceModifyRequest


IConferenceLocator::GetProfilesByTime

This method returns a collection of all instances of a meeting between the specified start and end time.

Syntax

HRESULT GetProfilesByTime(
[in] BSTR MeetingID,
[in] VARIANT StartTime,
[in] VARIANT EndTime,
[out] VARIANT*pConfProfiles);

Parameters

MeetingID
[in]Meeting ID of the requested profiles. The meeting ID cannot be NULL.
StartTime
[in] Date and time specifying the meeting’s start time. StartTime.vt must be set to VT_DATE, unless a zero is intended for the StartTime and EndTime parameters, in which case StartTime.vt and EndTime.vt must both be set to either VT_I2 or VT_I4.
EndTime
[in] Date and time specifying the meeting’s end time. EndTime.vt must be set to VT_DATE, unless a zero is intended for the StartTime and EndTime parameters, in which case StartTime.vt and EndTime.vt must both be set to either VT_I2 or VT_I4.
pConfProfiles
[out] Upon successful determination of matching meeting profiles, this variant contains a collection of matching conference profiles.

Return Values

Return code | Meaning
S_OK | The call returned successfully.
E_INVALIDARG | An invalid argument was passed in. One of the arguments passed in was NULL or didn’t contain the appropriate value.
CMS_E_CONFERENCE_NOT_EXIST | The requested conference based on the passed-in meeting ID was not recognized as an existing conference.
CMS_E_RECURRING_CONFERENCE_NOT_FOUND | The requested recurring conference based on the passed-in meeting ID didn’t occur in the specified time range.
CMS_E_CONFERENCE_NOT_FOUND | The requested conference based on the passed-in meeting ID didn’t occur in the specified time range.

Remarks

If both the start and end times are set to zero, the running instance of the conference (if one exists) is returned.


IConferenceLocator::GetProviderExtension

This method provides a means of calling through the locator to the CMS and retrieving a reference to the custom extension interface implemented by the specified CTP. The interface returned by this method is the same interface returned by the IConferenceTechnologyProvider::GetExtension method.

Syntax

HRESULT GetProviderExtension(
[in] BSTR ProviderClassID,
[out] VARIANT *pExtn);

Parameters

ProviderClassID
[in] The provider CLSID.
pExtn
[out] Upon success, contains the extension’s IDispatch interface pointer.

Return Values

Return code | Meaning
S_OK | The call returned successfully.
E_INVALIDARG | An invalid argument was passed in. One of the arguments passed in was NULL or didn’t contain the appropriate pointer value.
CMS_S_SHUTTING_DOWN | The CMS is currently shutting down.
CMS_E_PROVIDER_NOT_INITIALIZED | The requested provider has not been initialized yet.
CMS_E_PROVIDER_NOT_FOUND | The passed-in provider CLSID was not recognized.

See Also

IConferenceTechnologyProvider::GetExtension


IConferenceLocator::ConferenceJoinRequest

This method is called from the meeting’s ASP script when a client browser needs to join a conference.

Syntax

HRESULT ConferenceJoinRequest(
[in] BSTR MeetingID,
[in] BSTR PublicPassword,
[in] BSTR ClientIPAddress,
[in] VARIANT StartTime,
[out] VARIANT *pConfProfile,
[out] VARIANT *ProviderURLs );

Parameters

MeetingID
[in] The meeting ID of the requested profiles. The meeting ID cannot be NULL.
PublicPassword
[in] If the conference profile doesn’t need a password, an empty string in BSTR format must be passed. Otherwise, a conference profile password must be passed.
ClientIPAddress
[in] The client browser’s Internet protocol (IP) address.
StartTime
[in] Date and time specifying the meeting’s start time. If VT_NULL is passed, the current time is used as a default time.
pConfProfile
[out] Upon success, a variant containing the IConferenceProfile interface of the requested meeting.
ProviderURLs
[out] Upon success, a safe array of BSTR values containing the URLs for all the providers.

Return Values

Return code | Meaning
S_OK | The call returned successfully.
E_INVALIDARG | An invalid argument was passed in. One of the arguments passed in was NULL or didn’t contain the appropriate pointer value.
E_OUTOFMEMORY | Memory allocation failed during the request.
CMS_S_SHUTTING_DOWN | The join failed because the CMS is currently shutting down.
CMS_E_CONFERENCE_NOT_FOUND | The CMS did not recognize the conference identified by the passed-in meeting ID.
CMS_E_RECURRING_INSTANCE_NOT_WITHIN_TIME_BOUND | The recurring conference is not currently running and no instances occur during the time period specified.
CMS_E_AMBIGUOUS_RECURRING_JOIN | The recurring conference is not currently running and more than one instance of the recurring conference occurs during the time period specified.
CMS_E_CONFERENCE_NOT_RUNNING | All conference CTPs failed to start.
CMS_E_INVALID_CONFERENCE_PASSWORD | The password that was passed in did not match the one defined for public conferences with password. Note: An empty string must be passed in for public conferences with no password.
CMS_E_CTP_JOIN_REQUEST_FAILED | All CTPs failed or otherwise did not allow the join request.
CMS_E_ANONYMOUS_USER_DENIED_ACCESS | A request was made to join a private conference and the user context issuing the join request could not be determined.
CMS_E_USER_DENIED_ACCESS | A request was made to join a private conference and the account name of the user’s security context issuing the request did not match the account name of any of the allowed attendees.


IConferenceLocator::ConferenceModifyRequest

This method is called when the conference organizer needs to change a conference profile.

Syntax

HRESULT ConferenceModifyRequest(
[in] BSTR MeetingID,
[in] BSTR ClientIPAddress,
[in] CONFERENCE_PROPERTY PropertyID,
[in] VARIANT Value);

Parameters

MeetingID
[in] The meeting ID of the requested profiles. The meeting ID cannot be NULL.
ClientIPAddress
[in] The client browser’s IP address.
PropertyID
[in] A CONFERENCE_PROPERTY value. For more information, see the Remarks section.
Value
[in] The update value, which can be date and time, or an interface pointer based on the passed-in PropertyID value. For more information, see the Remarks section.

Return Values

Return code | Meaning
S_OK | The call returned successfully.
E_INVALIDARG | An invalid argument was passed in. One of the arguments passed in was NULL or didn’t contain the appropriate pointer value.
E_OUTOFMEMORY | Memory allocation failed during the request.
CMS_S_SHUTTING_DOWN | The join failed because the CMS is currently shutting down.
CMS_E_ANONYMOUS_USER_DENIED_ACCESS | The user context issuing the modification request could not be determined.
CMS_E_USER_DENIED_ACCESS | The account name of the user context issuing the request did not match the organizer's account name.
CMS_E_CONFERENCE_NOT_RUNNING | The conference is not currently running.
CMS_E_CONFERENCE_NOT_FOUND | The CMS did not recognize the conference identified by the passed-in meeting ID.

Remarks

The following enumerator defines the conference modifications:

typedef enum _CONFERENCE_PROPERTY
{
  EXTEND_TIME,         // Value = New time (vbDate)
  EXTEND_TIMEDELTA,    // Value = Time increment/decrement
                       // in minutes(long)
  EXTEND_RESOURCE,     // Value = VARIANT(ICMSResource)
  TERMINATE_IMMEDIATE  // Value = NULL
 } CONFERENCE_PROPERTY;
EXTEND_TIME
Defines an absolute time as requested by the client browser for extending the conference’s end time. Any GracePeriodAfter property value still applies.
EXTEND_TIMEDELTA
Defines a number of minutes by which the conference’s end time is to be modified, plus or minus 60 minutes; 0 is valid and does not affect the meeting’s duration.
EXTEND_RESOURCE
References an interface pointer to an ICMSResource object retrieved from the CMSAdmin ICMSResources collection.

A replacement of a conference resource must be another resource with the same set of CTPs. The effect of a resource replacement request is to ask each CTP to accept the alternate property set as parameters of the meeting.

TERMINATE_IMMEDIATE
Ends the current meeting. A grace period does not apply.

Note: A call to the ConferenceModifyRequest method needs to be made under the security context of the conference organizer.


IConferenceManager

This IUnknown-derived interface provides CTPs with the ability to access CMS services.

Methods

The IConferenceManager interface contains the following methods:

IConferenceManager::GetProfileStore

IConferenceManager::GetConferenceProviders

IConferenceManager::GetConfiguration

IConferenceManager::RegisterNotifyAbsolute

IConferenceManager::RegisterNotifyRelative

IConferenceManager::RegisterNotifyEvent

IConferenceManager::RevokeNotification

IConferenceManager::AvailabilityUpdateRequest


IConferenceManager::GetProfileStore

This method returns a reference to the instance of the profile stored in the CMS.

Syntax

HRESULT GetProfileStore([out] IConferenceProfileStore ** pCPStore);

Parameters

pCPStore
[out] Upon success, contains a pointer to the conference profile store.

Return Values

Return code | Meaning
S_OK | The call returned successfully.
E_INVALIDARG | An invalid argument was passed in. One of the arguments passed in was NULL or didn’t contain the appropriate pointer value.
CMS_S_SHUTTING_DOWN | The call was made while the CMS was shutting down.

Remarks

If the CMS fires a CM_GLOBALMAILBOXCHANGED event, any preexisting conference profile interface pointers are invalid and must be reinstantiated. To enable processing, the CTP needs to register with the CMS to receive notification when this event is fired.


IConferenceManager::GetConferenceProviders

This method returns a collection that defines a snapshot of the CTPs currently under CMS management.

Syntax

HRESULT GetConferenceProviders([out] IConferenceTechnologyProvider ***ppProviders);

Parameters

ppProviders
[out] Upon success, contains a pointer to the collection of the CTPs currently running under the CMS. The caller needs to use the CoTaskMemFree function to free the returned array.

Return Values

Return code | Meaning
S_OK | The call returned successfully.
E_INVALIDARG | An invalid argument was passed in. One of the arguments passed in was NULL or didn’t contain the appropriate pointer value.
CMS_S_SHUTTING_DOWN | The call was made while the CMS was shutting down.

Remarks

The caller must use the CoTaskMemFree function to free the allocated array. To obtain the count of elements in the returned array, see information in the MSDN library about the IMalloc::GetSize function. Note that the Imalloc interface is obtained through the CoGetMalloc function.


IConferenceManager::GetConfiguration

This method returns a reference to the CMS configuration object. This instance is used by all CMS modules and provides a consistent view of the configuration internally and to any interested CTP.

Syntax

HRESULT GetConfiguration([out] ICMSConfiguration **ppConfiguration);

Parameters

ppConfiguration
[out] Upon success, contains a pointer to the instance of the CMS configuration object.

Return Values

Return code | Meaning
S_OK | The call returned successfully.
E_INVALIDARG | An invalid argument was passed in. One of the arguments passed in was NULL or didn’t contain the appropriate pointer value.
CMS_S_SHUTTING_DOWN | The call was made while the CMS was shutting down.

Remarks

If the CMS fired the CMSNOTIF_ZONEPROPERTYCHANGED event, any preexisting ICMSConfiguration interface pointers are invalid and must be reinstantiated. To enable processing, the CTP needs to register with the CMS to receive notification when this event is fired.


IConferenceManager::RegisterNotifyAbsolute

This method provides CTPs with a simple mechanism to receive a callback at an absolute time in the future. However, there is no real-time guarantee on the exact time of the callback because system load can delay the call.

Syntax

HRESULT RegisterNotifyAbsolute(
[in] long Instance,
[in] IConferenceCallback *pCallback,
[in] long srcCookie,
[in] FILETIME AtTime,
[out]long *DestCookie);

Parameters

Instance
[in] The client instance that registered the callback. The parameter must equal the value passed to the CTP during its initialization.
pCallBack
[in] The callback interface pointer.
srcCookie
[in] The CTP-defined value that is passed without modification in the callback notification.
AtTime
[in] The FILETIME value at which the callback is requested.
DestCookie
[out] Upon success, sets to value > 0, and used if the RevokeNotification method needs to be called.

Return Values

Return code | Meaning
S_OK | The call returned successfully.
E_INVALIDARG | An invalid argument was passed in. One of the arguments passed in was NULL or didn’t contain the appropriate pointer value.
CMS_S_SHUTTING_DOWN | The call was made while the CMS was shutting down.

Remarks

The callback can occur on any available thread in the CMS and, because the CTP is free-threaded, can occur simultaneously with other callbacks or CTP calls into the CMS. The CTPs must be thread safe.

The srcCookie parameter allows the callback to be identified to a specific instance of the registration. This can be more convenient than supplying a difference instance of the IConferenceCallback interface for all callbacks.

The destCookie parameter can be used to cancel the callback request through the RevokeNotification method. Standard HRESULT returns apply. No duplicate of any destCookie parameter is returned for any pending callback.

Callbacks are not honored if the CMS server shuts down or if the HostServer property is modified.

The Instance parameter must equal the value passed to the CTP during its initialization.

By using CMS-provided event notification, CTPs share the CMS-provided thread pool for efficient and scalable processing.


IConferenceManager::RegisterNotifyRelative

This method registers a relative timer callback.

Syntax

HRESULT RegisterNotifyRelative(
[in] long Instance,
[in] IConferenceCallback *pCallback,
[in] long SrcCookie,
[in] ULONG numMilliSecs,
[out]long *DestCookie);

Parameters

Instance
[in] The client instance registering the callback. The Instance parameter must equal the value passed to the CTP during its initialization.
pCallBack
[in] The callback interface pointer.
SrcCookie
[in] A CTP defined value, which is passed without modification in the callback notification.
numMilliSecs
[in] Number of milliseconds after which the callback needs to fire.
DestCookie
[out] Upon success, sets to value > 0, and used if the RevokeNotification method needs to be called.


IConferenceManager::RegisterNotifyEvent

This method enables the calling CTP to register a callback for CMS events. Multiple events can be registered by indicating them in the Events parameter.

Syntax

HRESULT RegisterNotifyEvent(
[in] long Instance,
[in] IConferenceCallback * pCallback,
[in] long Events,
[in] long SrcCookie,
[out]long *DestCookie);

Parameters

Instance
[in] The client instance registering the callback. This parameter must equal the value passed to the CTP during its initialization.
pCallback
[in] The callback interface pointer.
Events
[in] An event mask consisting of one or more CMS_EVENTS to cause callback notification. For information about CMS_EVENTS, see the Remarks section.
SrcCookie
[in] User-defined value, which is—passed without modification in the callback.
DestCookie
[out] Upon success, sets to value > 0, and used if the RevokeNotification method needs to be called.

Return Values

Return code | Meaning
S_OK | The call returned successfully.
E_INVALIDARG | An invalid argument was passed in. One of the arguments passed in was NULL or didn’t contain the appropriate pointer value.
CMS_S_SHUTTING_DOWN | The call was made while the CMS was shutting down.

Remarks

The DestCookie parameter is used to revoke the associated registered notification. If multiple events are set in the event mask, all events are revoked. If an event is registered multiple times in separate calls to the RegisterNotifiyEvent method, only a single instance of the event is revoked when the specific DestCookie is used in a call to the RevokeNotication method.

The Instance parameter must equal the value passed to the CTP during its initialization.

The SrcCookie parameter can be used by the calling process to distinguish specific event registrations during the associated callback.

The following enumerator defines the event values that can be used and the meaning of the Param parameter during the associated callback.

typedef enum _CMS_EVENTS
{
/*
The event is returned whenever a RegisterNotifyAbsolute or RegisterNotifyRelative callback is fired. The Param equals the SrcCookie that was defined during call registration.
*/
CM_TIMEREVENT = 0x00010000,

/*
Sent by the CMS immediately when the CMS service is starting. Param = NULL
*/
CM_STARTING = 0x00020000,

/*
This event is sent when the CMS has completed initialization.
Param = NULL
*/
CM_RUNNING = 0x00040000,

/*
This event is fired when the CMS transitions from the Running to Stopped state. When the CMS is in the Stopped state, pointers to the ProfileStore, profiles, ICMSZone, ICMSResources, and any other state maintained by the CMS are no longer valid. Attempts to access them or call methods on previously stored pointers results in an error (but  not a crash).
Param = NULL
*/
CM_STOPPING = 0x00080000,

/*
MasterAlias for the Zone has changed. Param = NULL
When this event is fired, existing IConferenceProfile interface pointers become invalid and must be reinstantiated.
*/

CM_GLOBALMAILBOXCHANGED = 0x00100000,

/*
This event is sent whenever the profile store contains a new meeting. The Param field contains a reference to the associated IConferenceProfile interface.
*/
CP_CREATE = 0x00200000,   //Param = (IConferenceProfile *) pProfile

/*
This event notifies that the profile, as specified by the IConferenceProfile interface passed in the param field, has been modified.
*/
CP_MODIFY = 0x00400000,   //Param = (IConferenceProfile *) pProfile

/*
This event is a notification that the profile, as specified by the IConferenceProfile interface in the Param field, has been deleted from the profile store.
*/
CP_DELETE = 0x00800000,   //Param = (IConferenceProfile *) pProfile
} CMS_EVENTS;


IConferenceManager::RevokeNotification

The method provides the mechanism to cancel the registration of a callback.

Syntax

HRESULT RevokeNotification(
[in] long hInst,
[in] long DestCookie);

Parameters

hInst
[in] The client instance registering the callback. This parameter must equal the value passed to the CTP during its initialization.
DestCookie
[in] The instance of the registration to revoke.

Return Values

Return code | Meaning
S_OK | The call returned successfully.
E_INVALIDARG | An invalid argument was passed in. One of the arguments passed in was NULL or didn’t contain the appropriate pointer value.
CMS_S_SHUTTING_DOWN | The call was made while the CMS was shutting down.

Remarks

The DestCookie parameter specifies the instance of the registration. After a registration has been revoked, the cookie is invalid and is not to be used again because the CMS may reuse the value for a subsequent binding.

If the registration includes multiple events, all events associated with the cookie are revoked. If the same events are registered against another cookie, the callbacks are unaffected.


IConferenceManager::AvailabilityUpdateRequest

A given CTP calls this method to ask the CMS to republish the CTP resource free/busy availability.

Syntax

HRESULT AvailabilityUpdateRequest(
[in] IConferenceTechnologyProvider *pProvider,
[in] FILETIME StartTime,
[in] FILETIME EndTime);

Parameters

pProvider
[in] The IConfereceTechnologyProvider interface of the calling CTP.
StartTime
[in] The start time for when availability has changed.
EndTime
[in] The end time for when availability has changed.

Return Values

Return code | Meaning
S_OK | The call returned successfully.
E_INVALIDARG | An invalid argument was passed in. One of the arguments passed in was NULL or didn’t contain the appropriate pointer value.
CMS_S_SHUTTING_DOWN | The call was made while the CMS was shutting down.

Remarks

A specific CTP calls this method as a notification that the CMS meeting agent must republish the CTP resource mailbox’s free/busy availability.

Note: The CMS batches calls to the IConferenceTechnologyProvider::GetAvailability method for better performance.


IConferenceCallback

This IUnknown-derived interface is a generic notification interface used throughout the CMS and CTP interfaces.

Methods

The IConferenceCallback interface contains the following method.

IConferenceCallBack::OnNotification

© 2000-2001 Microsoft Corporation. All rights reserved.


IConferenceCallback::OnNotification

This method is called in response to any notification registered against the instance of the IconferenceCallback object.

HRESULT OnNotification(
[in] long Event,
[in] long srcCookie,
[Out] PVOID Param);

Parameters

Event
[in] The event for which the callback happened.
srcCookie
[in] The cookie passed in while registering for the event.
Param
[in] Pointer to data type that is relevant to the Event and SrcCookie parameters.

Return Values

Return code | Meaning
S_OK | The call returned successfully.
E_INVALIDARG | An invalid argument was passed in. One of the arguments passed in was NULL or didn’t contain the appropriate pointer value.
CMS_S_SHUTTING_DOWN | The call was made while the CMS was shutting down.


IConferenceProfileStore

CTPs interested in the content of the store can access this IUnknown-derived interface.

Methods

The IConferenceProfileStore interface has the following methods:

IConferenceProfileStore::GetConferenceProfile

IConferenceProfileStore::GetProfilesByTime

IConferenceProfileStore::GetProfilesCreatedSince

IConferenceProfileStore::GetProviderAvailabilityByPropertySum


IConferenceProfileStore::GetConferenceProfile

This method returns a reference to the instance of a meeting profile identified by the MeetingID parameter.

Syntax

HRESULT GetConferenceProfile(
[in] BSTR MeetingID,
[out] IConferenceProfile **pProfile);

Parameters

MeetingID
[in] The meeting ID of the requested profiles. The meeting ID cannot be NULL.
pProfile
[out] Upon success, contains a valid interface pointer to the requested conference profile.

Return Values

S_OK upon success; otherwise, other HRESULT values upon failure.

Remarks

This method needs to be used whenever a single conference profile is to be retrieved. If the meeting ID is for a recurring meeting, the master instance of the meeting is returned.


IConferenceProfileStore::GetProfilesByTime

This method retrieves all profiles for meetings specified inclusively between StartTime and EndTime values. Each instance of a recurring meeting is returned in the collection with its MeetingID set.

Syntax

HRESULT GetProfilesByTime(
[in] BSTR ProviderClassID,
[in] BSTR MeetingID,
[in] FILETIME StartTime,
[in] FILETIME EndTime,
[out] IConferenceProfiles **Profiles);

Parameters

ProviderClassID
[in] The provider CLSID. An empty string or NULL obtains profiles for all CTPs.
MeetingID
[in] The meeting ID of the requested profiles. An empty string obtains all meetings.
StartTime
[in] A FILETIME value specifying the start time.
EndTime
[in] A FILETIME value specifying the end time.
Profiles
[out] Contains a valid IConferenceProfiles interface pointer.

Return Values

S_OK upon success; otherwise, other HRESULT values upon failure.

Remarks

If the ProviderClassID parameter is an empty string or NULL, all profiles for all CTPs are returned. If ProviderClassID equals the GUID of a specific CTP, only profiles booked against resources associated with the CTP are returned.

If the MeetingID parameter is not the empty string, it is assumed to be the ID of a master recurring meeting, thus restricting the returned profiles to only instances of the recurring meeting. This collection also includes exceptions to the recurrence with differing meeting IDs.

If no profiles are active during the specified period, a collection of no elements is returned.


IConferenceProfileStore::GetProfilesCreatedSince

This method retrieves all profiles for meetings specified by the creation time. The returned collection does not expand instances of recurring meetings.

Syntax

HRESULT GetProfilesCreatedSince(
[in] BSTR ProviderClassID,
[in] FILETIME CreateTime,
[out] IConferenceProfiles **Profiles);

Parameters

ProviderClassID
[in] The provider CLSID. An empty string obtains all CTP resources.
CreateTime
[in] A FILETIME value specifying when the conference profiles were created.
Profiles
[out] Upon success, contains a valid IConferenceProfiles interface pointer.

Return Values

S_OK upon success; otherwise, other HRESULT values upon failure.


IConferenceProfileStore::GetProviderAvailabilityByPropertySum

Platform SDK: Exchange 2000 Server

IConferenceProfileStore::GetProviderAvailabilityByPropertySum —Reserved

The CTP must implement its own mechanism for determining availability. For more information, see IConferenceTechnologyProvider::GetAvailability.


IConferenceProfiles

This automation object is used to represent a collection of conference profiles.

The IConferenceProfiles interface contains the following properties.

Name | Type | Access
IConferenceProfiles::Count | Long | Read-only
IConferenceProfiles::Item (default property) | IConferenceProfile object | Read/write
IConferenceProfiles::NewEnum | IUnknown | Read-only


IConferenceProfiles::Count Property

This property contains the count of items in the collection.

Syntax

HRESULT get_Count( [out, retval] long * Count );

Parameters

Count
The number of IConferenceProfile objects in the collection.

Return Values

S_OK upon success; otherwise, other HRESULT values upon failure.


IConferenceProfiles::Item

This property contains a single ConferenceProfile object from the collection.

Syntax

HRESULT get_Item([in] VARIANT indexKey,
[out, retval] IConferenceProfile **pVal);

Parameters

indexKey
[in] Either a numeric value (VT_I2 or VT_I4), an index into a collection, or a BSTR value (VT_BSTR) representing the meeting ID of a contained profile. The numeric index starts at 1. Use either a string or a numeric index, but not both.
pVal
[out] Upon success, a valid IConferenceProfile interface if one is found.

Return Values

S_OK upon success; otherwise, other HRESULT values upon failure.

Remarks

If the collection contains the expansion of a recurring meeting, a Meeting ID index returns the first (time ordered) of the associated profiles.

An invalid index parameter still returns S_OK; however, the returned profile is NULL.


IConferenceProfiles::NewEnum Property

This property contains the automation-compatible enumerator for the collection.

Syntax

HRESULT get__NewEnum([out, retval] IUnknown **pVal);

Parameters

pVal
[out] A pointer to the enumerator object’s IUnknown interface.

Return Values

S_OK upon success; otherwise, other HRESULT values upon failure.

Remarks

This object must be returned even if it contains no members; the count is zero.


IConferenceProfile

This non-creatable automation object is used to represent a snapshot of the definition of a meeting in the profile store.

Methods

The IConferenceProfile interface has the following methods:

IConferenceProfile::FindRecipientByAccountName

IConferenceProfile::FindRecipientByEmailAlias

IConferenceProfile::Update

Properties

The IConferenceProfile interface has the following properties.

Name | Type | Access
IConferenceProfile::MeetingID | String | Read-only
IConferenceProfile::Resource | VARIANT | Read-only
IConferenceProfile::Recipients | VARIANT(VT_ARRAY)( IConferenceAttendee) | Read-only
IConferenceProfile::Organizer | VARIANT (IConferenceAttendee) | Read-only
IConferenceProfile::Importance | Long | Read-only
IConferenceProfile::CreationDate | VARIANT(VT_DATE) | Read-only
IConferenceProfile::Starttime | VARIANT(VT_DATE) | Read-only
IConferenceProfile::Endtime | VARIANT(VT_DATE) | Read-only
IConferenceProfile::IsRecurring | VARIANT_BOOL | Read-only
IConferenceProfile::IsPublic | VARIANT_BOOL | Read-only
IConferenceProfile::PublicPassword | String | Read-only
IConferenceProfile::UserProperty Property Put | VARIANT | Read/Write
IConferenceProfile::UserProperty Property Get | VARIANT | Read/write


IConferenceProfile::FindRecipientByAccountName

This method provides an indexed search into the Recipient array.

Syntax

HRESULT FindRecipientByAccountName(
[in] BSTR AccountName,
[out] VARIANT *Recipient);

Parameters

AccountName
[in] A BSTR value representing the account name.
Recipient
[out] Upon success, a variant containing the IDispatch interface to the IConferenceAttendee object. NULL can be passed in if the caller needs to check the existence of a user.

Return Values

S_OK upon success; otherwise, other HRESULT values upon failure.


IConferenceProfile::FindRecipientByEmailAlias

This method provides an indexed search into the Recipients array.

Syntax

HRESULT FindRecipientByEmailAlias(
[in] BSTR EmailAlias,
[out] VARIANT *Recipient);

Parameters

EmailAlias
[in] A BSTR value representing the e-mail alias.
Recipient
[out] Upon success, a variant containing the IDispatch interface to the IConferenceAttendee object. NULL can be passed in if the caller needs to check the existence of the e-mail alias.

Return Values

S_OK upon success; otherwise, other HRESULT values upon failure.


IConferenceProfile::Update

This method writes any modified or new user properties to the associated meeting profile.

Syntax

HRESULT Update();

Parameters

None

Return Values

Return code | Meaning
S_OK | The call returned successfully.
E_INVALIDARG | An invalid argument was passed in. One of the arguments passed in was NULL or didn’t contain the appropriate pointer value.
E_OUTOFMEMORY | Memory allocation failed during the request.
CMS_E_CP_TRANSIENT_PROFILE | The update failed because the state of the conference profile is CP_TRANSIENT.
CMS_E_CP_DELETED_PROFILE | The update failed because the state of the conference profile is CP_DELETED.
E_UNEXPECTED | An unexpected error occurred.


IConferenceProfile::MeetingID Property

This property contains the meeting ID of the associated meeting.

Syntax

HRESULT get_MeetingID([out, retval] BSTR *pVal);

Parameters

pVal
[out] The meeting ID in BSTR format.

Return Values

S_OK upon success; otherwise, other HRESULT values upon failure.


IConferenceProfile::Resource Property

This property contains a pointer to the resource object used to book the meeting.

Syntax

HRESULT get_Resource([out,retval] VARIANT *pVal);

Parameters

pVal
[out] A variant containing the IDispatch interface of the ICMSResource object.

Return Values

Return code | Meaning
S_OK | The call returned successfully.
CMS_E_CP_TRANSIENT_PROFILE | The profile is no longer valid.
HRESULTs | Standard COM error codes.

Remarks

The ICMSResource object reflects the values of the resource’s properties when the meeting was scheduled, not the current values defined on the resource.


IConferenceProfile::Recipients Property

This property contains an array of all (distribution list (DL) expanded) invitees of the meeting’s attendees.

Syntax

HRESULT get_Recipients([out,retval] VARIANT * Recipients);

Parameters

Recipients
[out] Upon success, contains a safe array of all DL-expanded invitees of the meeting’s attendees.

Return Values

Return code | Meaning
S_OK | The call returned successfully.
E_INVALIDARG | Invalid argument.
E_OUTOFMEMORY | Memory allocation failed during the request.
E_UNEXPECTED | An unexpected error occurred.
HRESULTs | Standard COM error codes.


IConferenceProfile::Organizer Property

This property contains the IConferenceAttendee object of the meeting organizer.

Syntax

HRESULT get_Organizer([out, retval]VARIANT *pVal);

Parameters

pVal
[out] Upon success, the variant contains an IDispatch interface to the organizer’s IConferenceAttendee object.

Return Values

Return code | Meaning
S_OK | The call returned successfully.
E_INVALIDARG | Invalid argument.
E_OUTOFMEMORY | Memory allocation failed during the request.
E_UNEXPECTED | An unexpected error occurred.
HRESULTs | Standard COM error codes.


IConferenceProfile::Importance Property

This property contains the importance value.

Syntax

HRESULT get_Importance([out,retval] long *Level);

Parameters

Level
[out] Upon success, contains the importance value, which can be one of the following: Normal = 0, Urgent = 1, or Low = 2

Return Values

Return code | Meaning
S_OK | The call returned successfully.
E_POINTER | The out parameter is NULL.
E_INVALIDARG | Invalid argument.
E_OUTOFMEMORY | Memory allocation failed during the request.
E_UNEXPECTED | An unexpected error occurred.
HRESULTs | Standard COM error codes.


IConferenceProfile::CreationDate Property

This property contains the date the profile was created.

Syntax

HRESULT get_CreationDate([out,retval] VARIANT *Date);

Parameters

Date
[out] Upon success, contains the creation date of the profile.

Return Values

Return code | Meaning
S_OK | The call returned successfully.
E_POINTER | The out parameter is NULL.
E_INVALIDARG | Invalid argument.
E_OUTOFMEMORY | Memory allocation failed during the request.
E_UNEXPECTED | An unexpected error occurred.
HRESULTs | Standard COM error codes.


IConferenceProfile::StartTime Property

This property contains the start time of the meeting.

Syntax

HRESULT get_StartTime([out,retval] VARIANT *StartTime);

Parameters

StartTime
[out] Upon success, contains the start time of the meeting.

Return Values

Return code | Meaning
S_OK | The call returned successfully.
E_POINTER | The out parameter is NULL.
E_INVALIDARG | Invalid argument.
E_OUTOFMEMORY | Memory allocation failed during the request.
E_UNEXPECTED | An unexpected error occurred.
HRESULTs | Standard COM error codes.


IConferenceProfile::EndTime Property

This property contains the end time of the meeting. The value of this property also represents any accepted time-extension request during the conference.

Syntax

HRESULT get_EndTime([out,retval] VARIANT *EndTime)

Parameters

EndTime
[out] Upon success, contains the end time of the meeting.

Return Values

Return code | Meaning
S_OK | The call returned successfully.
E_POINTER | The out parameter is NULL.
E_INVALIDARG | Invalid argument.
E_OUTOFMEMORY | Memory allocation failed during the request.
E_UNEXPECTED | An unexpected error occurred.
HRESULTs | Standard COM error codes.


IConferenceProfile::IsRecurring Property

This property determines whether the conference is recurring.

Syntax

HRESULT get_IsRecurring( [out,retval] VARIANT_BOOL *IsRecurring);

Parameters

IsRecurring
[out] Set to VARIANT_TRUE if the conference is recurring, or VARIANT_FALSE if not.

Return Values

Return code | Meaning
S_OK | The call returned successfully.
E_POINTER | The out parameter is NULL.
E_INVALIDARG | Invalid argument.
E_OUTOFMEMORY | Memory allocation failed during the request.
E_UNEXPECTED | An unexpected error occurred.
HRESULTs | Standard COM error codes.


IConferenceProfile::IsPublic Property

This property is set to true if the Allow External Attendees flag was set during the scheduling of the meeting.

Syntax

HRESULT IsPublic([out,retval] VARIANT_BOOL *IsPublic);

Parameters

IsPublic
[out] Set to VARIANT_TRUE if the meeting is public or VARIANT_FALSE if not.

Return Values

S_OK upon success; otherwise, other HRESULT error values upon failure.


IConferenceProfile::PublicPassword Property

This property contains the public password if the meeting is public.

Syntax

HRESULT get_PublicPassword([out,retval] BSTR *Password);

Parameters

Password
[out] Contains the public password. The public password is an optional 0- to 32-character password required for attendees to access the meeting access page.

Return Values

S_OK upon success; otherwise, other HRESULT error values upon failure.


IConferenceProfile::UserProperty Property [Property Put]

This property provides a read/write namespace for providers to associate custom property values on a meeting profile.

Syntax

HRESULT put_UserProperty([in] BSTR Name,
[in] BSTR ProviderClassID,
[in] VARIANT newVal);

Parameters

Name
[in] A user-defined property name.
ProviderClassID
[in] A valid provider CLSID that is passed as the GUID for the property set.
newVal
[in] The property value to set or update.

Return Values

S_OK upon success; otherwise, other HRESULT values upon failure.

Remarks

The ProviderClassID parameter provides a unique namespace in which a CTP can store custom properties.

Setting a value in an existing property updates the property. Setting a value that doesn’t exist creates the property. Setting a value of VT_EMPTY erases the property.

Property values are persisted to the store when the Update method is called.

See Also

IConferenceProfile::Update

© 2000-2001 Microsoft Corporation. All rights reserved.


IConferenceProfile::UserProperty Property [Property Get]

This property provides a read/write namespace for providers to associate custom property values on a meeting profile.

Syntax

HRESULT get_UserProperty([in] BSTR Name,
[in] BSTR ProviderClassID,
[out, retval] VARIANT *Value);

Parameters

Name
[in] A string representing a property name. The property name can be defined by the provider or can be a MAPI property name. For more information, see the Remarks section.
ProviderClassID
[in] A valid provider CLSID that is passed as the GUID for the property set. If NULL, PS_PUBLIC_STRINGS is used as the default GUID for the property set.
Value
[out] Contains the value of the requested property.

Return Values

S_OK upon success; otherwise, other HRESULT values and a variant of VT_ERROR upon failure.

Remarks

The ProviderClassID parameter provides a unique namespace in which a CTP can store custom properties. If an empty string is used, the named property from the Outlook form’s namespace is returned.

If the named property does not exist, the returned variant contains a VT_ERROR.

The following predefined property names can be used if the ProviderClassID parameter is the BSTR representation of CDO. Other MAPI property names can also be used. Note that MAPI property names may not be supported in the future, and CDO needs to be used instead.

Predefined Property Names

Property name | Description
URL or PR_URL_NAME | Returns an HTTP-based URL.
BODY or PR_BODY_HTML | The PR_BODY_HTML property contains the HTML version of the message text.
SUBJECT or PR_SUBJECT | The PR_SUBJECT property contains the full subject of a message.


IConferenceAttendee

This non-creatable automation object is used to identify meeting attendees. Properties that are not known about an attendee return an empty string. Note that these properties are set only if IConferenceAttendee is the interface obtained from joining a conference, not from a conference profile.

Properties

Name | Type | Access
DisplayName Property | String | Read-only
EmailAlias Property | String | Read-only
MemberZone Property | String | Read-only
IPAddress Property | String | Read-only
AccountName Property | String | Read-only


IConferenceAttendee::DisplayName Property

This is the DisplayName property of the meeting attendee.

Syntax

HRESULT get_DisplayName([out,retval] BSTR *pDisplayName);

Parameters

pDisplayName
[out] Contains the DisplayName property of the meeting attendee if known, or an empty string otherwise.


IConferenceAttendee::EmailAlias Property

This is the EmailAlias property of the meeting attendee.

Syntax

HRESULT EmailAlias([out, retval] BSTR * pEmailAlias);

Parameters

pEmailAlias
[out] Contains the e-mail alias of the meeting attendee if known, or an empty string otherwise.


IConferenceAttendee::MemberZone Property

This is the MemberZone property of an attendee

Syntax

HRESULT get_MemberZone([out,retval] BSTR *pZoneName);

Parameters

pZoneName
[out] CMS zone property for this attendee if known, or an empty string otherwise.


IConferenceAttendee::IPAddress Property

This is the IPAddress property of an attendee.

Syntax

HRESULT get_IPAddress([out,retval] BSTR *pIP);

Parameters

pIP
[out] The IP address for this attendee if known, or an empty string otherwise.


IConferenceAttendee::AccountName Property

This is the AccountName property of the attendee.

Syntax

HRESULT get_AccountName([out, retval] BSTR *pAccount);

Parameters

pAccount
[out] The attendee’s Windows NT account name if known, or an empty string otherwise.


Conference Technology Provider Service

All CTPs must implement this IUnknown-derived interface. It must be implemented as an in-process free-threaded component. Two GUIDs are associated with a given CTP. The first is the CTP’s CLSID, which is the COM class identifier for the object used to instantiate the object. The second is the ProviderClassID, which is used throughout the CMS and by resources to identify a specific CTP; it is retrieved from the CTP definition in the Active Directory tree for the CMS.

The definition for the ConferenceTechnologyProvider coclass follows:

coclass XXXX.ConferenceTechnologyProvider
{
  [default] interface IConferenceTechnologyProvider;
};


IConferenceTechnologyProvider

Each CTP must implement this IUnknown-derived interface as a in-process, free-threaded component.

Methods

The IConferenceTechnologyProvider interface has the following methods:

IConferenceTechnologyProvider::ProviderClassID

IConferenceTechnologyProvider::ProviderName

IConferenceTechnologyProvider::Initialize

IConferenceTechnologyProvider::Uninitialize

IConferenceTechnologyProvider::GetExtension

IConferenceTechnologyProvider::GetAvailablity

IConferenceTechnologyProvider::StartConference

IConferenceTechnologyProvider::StopConference

IConferenceTechnologyProvider::JoinRequest

IConferenceTechnologyProvider::PreJoinRequest

IConferenceTechnologyProvider::PostJoinRequest

IConferenceTechnologyProvider::ConfirmScheduleRequest

IConferenceTechnologyProvider::AbortScheduleRequest


IConferenceTechnologyProvider::ProviderClassID

This method returns a string representing the provider’s CLSID. The CLSID is used throughout the CMS and by resources to identify a specific CTP.

Syntax

HRESULT ProviderClassID([out] BSTR *ProviderGUID);

Parameters

ProviderGUID
[out] A string representing the provider’s CLSID.

Return Values

S_OK upon success; otherwise, other HRESULT values upon failure.

Remarks

The CLSID returned by this method is used to associate a CTP with a resource. The CTP must maintain the same ProviderClassID value for the life of the provider’s installation with the CMS. The CTP installation setup publishes this CLSID in the DS.

Because the CMS does not use the value of this property to instantiate the CTP, the CTP can be upgraded without the need to reconfigure resources.


IConferenceTechnologyProvider::ProviderName

This method returns a string representing the provider name.

Syntax

HRESULT ProviderName([out] BSTR *ProviderName);

Parameters

ProviderName
[out] An alphanumeric character string representing the provider name.

Return Values

S_OK upon success; otherwise, other HRESULT values upon failure.

Remarks

The ProviderName string consists of alphanumeric characters that the CMS uses to textually identify a CTP. The CMS uses this name in event logging, and to identify a CTP to the user. The CTP installation setup defines this text and publishes it in the DS.


IConferenceTechnologyProvider::Initialize

The CMS calls this method immediately following the instantiation of the CTP. This call initializes the CTP with a reference to the CMS interface, and with the instance ID that the CTP uses when registering and revoking notification events.

Syntax

HRESULT Initialize([in] IConferenceManager *pCMS,
[in] long Instance);

Parameters

pCMS
[in] An IConferenceManager interface.
Instance
[in] The CTP instance ID, specified by the CMS.

Return Values

S_OK upon success; otherwise, other HRESULT values upon failure.

Remarks

The Instance parameter supplies the CTP with the value that it must use whenever it registers for any CMS callback events.

The CTP needs to use this method to set and initialize the global state that has to be maintained for the lifetime of the CTP in the CMS.

Any returned error value is considered a fatal error. No subsequent calls need to be made to the CTP if initialization fails. Other CTPs are unaffected and can be called as normal. The CTP needs to log error events and the reason for failure. The CTP also needs to release any allocated resources before returning an error value, because the IConferenceTechnologyProvider::UnInitialize method is not called if this method returns an error.


IConferenceTechnologyProvider::UnInitialize

The CMS calls this method immediately before releasing the CTP instance.

Syntax

HRESULT UnInitialize();

Parameters

None.

Return Values

S_OK upon success; otherwise, other HRESULT values upon failure.

Remarks

The CTP needs to free all memory and prepare for termination. The CMS ignores the returned HRESULT. This method is not called if the Initialize call returned an error to the CMS. Hence, the CTP needs to release any allocated resources before returning an error value from the call to the Initialize method.


IConferenceTechnologyProvider::GetExtension

This method returns a pointer to the private interface for the CTP.

Syntax

HRESULT GetExtension([out] IDispatch **pDisp);

Parameters

pDisp
[out] An IDispatch interface that provides the caller with access to the CTP.

Return Values

S_OK upon success; otherwise, other HRESULT values upon failure.

Remarks

This method provides a mechanism for a CTP to publish a proprietary interface from within the instance of the CTP that CMS instantiated. The returned interface is usually used by the conference’s ASP pages through the IConferenceLocator::GetProviderExtension method. The CTP is not required to implement and publish such an interface.


IConferenceTechnologyProvider::GetAvailability

This method is called whenever a meeting is scheduled to obtain the availability of each of the CTPs associated with the meeting’s resources.

Syntax

HRESULT GetAvailability(
[in] ICMSResource **pResources,
[in] long NumResources,
[in] DWORD dwReserved,
[in] FILETIME StartTime,
[in] FILETIME EndTime,
[in] long cMinutes,
[out] long *rgAvailablity);

Parameters

pResources
[in] An array of ICMSResource interface pointers.
NumResources
[in] The count of resources to examine.
dwReserved
[in] Reserved.
StartTime
[in] A FILETIME value representing the start time of the requested meeting.
EndTime
[in] A FILETIME value representing the end time of the requested meeting.
cMinutes
[in] A value representing the number of minutes in the requested meeting.
rgAvailability
[out] Upon success, contains the availability of every passed-in resource. Every long value in the rgAvailability array represents one minute if the number of resources is less than or equal to 32; every two longs (rgAvailability[n+0] and [n+1]) represent one minute if the number of resources is less than or equal to 64 and more than 32; and so on. The least significant bit (LSB) represents the first resource, where zero means that the resource is free during the minute and nonzero means that the resource is busy during the minute. For more information, see the Remarks section.

Return Values

S_OK upon success; otherwise, other HRESULT values upon failure.

Remarks

The GetAvailability method is called whenever a conference is scheduled. The conference can be scheduled when the free/busy status at the time of scheduling is free. This method is called while the new meeting is processed so that subsequent meetings can be automatically rejected if any resource becomes busy. The availability of every passed-in resource must be computed.

For the specified array of resources, during the specified time period, the CTP must return an array representing the free/busy availability per time division for each resource. The CTP can use the GetProfilesByTime method to compare the currently scheduled meeting against its configured maximum time.

The memory array to which the rgAvailability parameter refers is set by the CTP to indicate the free/busy status in the specified time for each of the specified resources. This memory is structured as an array of long values, each long representing a block of 32 resources for a specific minute in the period. If more than 32 resources are specified, multiple sequential long values represent each minute period. The LSB represents the first resource in the first long value. Sequential blocks of these resource bit-field long values represent each minute in the specified period.

A CTP is responsible for maintaining the current end time and the resource defined on running conferences with respect to any modification requests. A CTP receives a CP_MODIFY event whenever a modification request is committed. When computing the free/busy status directly from the ProfileStore (through the GetProfilesByTime method), the CTP needs to override the end time and the resource with the current values returned during any CP_MODIFY event.

Unless the conferencing provider implements a caching scheme, this method can be very expensive to call because every call results in a request to the conferencing provider asking for all the conference profiles in the requested time range. This means that the provider is required to expand recurring meetings that may not even pertain.

Any return value other than S_OK stops the CMS from publishing the free/busy status. A CTP that does not implement this functionality must also return S_OK to avoid blocking the free/busy status of any grouped resources from being published.


IConferenceTechnologyProvider::StartConference

The CMS calls this method to notify the CTP that the associated conference needs to be started.

Syntax

HRESULT StartConference([in] BSTR MeetingID,
[in] IConferenceProfile *pCP);

Parameters

MeetingID
[in] A string representing the meeting ID.
pCP
[in] A valid interface to the conference profile object.

Return Values

S_OK upon success; otherwise, other HRESULT values upon failure.

Remarks

The StartConference method is called when the conference is scheduled to start, minus any configured grace period. So, if the conference is scheduled to start at 10:00 A.M. and the grace period is 15 minutes, this method is called at 9:45 A.M. This method is only called for conferences hosted in the site. When the site is hosting a referral, the conference is created at the time of the first referral. This method creates the conference object that lives for the lifetime of the conference. This method is called exactly once per conference. The JoinRequest method is only called between the time that the StartConference method is called through the time that the StopConference method is called.

The CMS also calls this method to restart conferences following the CM_GLOBALMAILBOXCHANGED notification event to synchronize the CTP with the conferences held in the new store.

Returning any error value is considered a fatal error condition; it stops any join or other methods for the associated conference from being called. Any other CTP hosting this conference is unaffected. Upon failure, this CTP does not receive any frame space in the client browser’s window. The CTP needs to log any associated event messages.


IConferenceTechnologyProvider::StopConference

The CMS calls this method to indicate that the CTP needs to immediately terminate the associated conference.

Syntax

HRESULT StopConference([in] BSTR MeetingID);

Parameters

MeetingID
[in] A string representing the meeting ID.

Return Values

S_OK upon success; otherwise, other HRESULT values upon failure.

Remarks

The StopConference method is called at the conference’s scheduled end time, plus the grace period. So, if the conference is scheduled to end at 11:00 P.M. and the grace period is 15 minutes, this method is called at 11:15 P.M. This method is responsible for the final release and deletion of the conference object. The CMS ignores the return value. The CTP needs to log any associated event message as necessary.


IConferenceTechnologyProvider::JoinRequest

This method enables an attendee specified by the IConferenceAttendee interface pointer to join a conference specified by the meeting ID.

Syntax

HRESULT JoinRequest( [in] BSTR MeetingID,
[in] IConferenceAttendee * pAttendee,
[out] BSTR * pURL);

Parameters

MeetingID
[in] A string representing a meeting ID.
pAttendee
[in] An IConferenceAttendee interface specifying the attendee requesting to join the meeting.
pURL
[out] A URL for the conferencing Web page containing the response to the join request.

Return Values

S_OK upon success; otherwise, other HRESULTs upon failure.

Remarks

The JoinRequest method is called whenever a user wants to join a conference hosted in the site between the time that the StartConference method is called and the time that the StopConference method is called.

JoinRequest always returns the URL of the conferencing-service-specific Web page so that the actual joining can occur.

The URL field can be an empty string regardless of the HRESULT value. If the string is empty, and if the call is successful, the CMS does not display the CTP frame to the client browser. If empty in the error condition, only the HRESULT is returned to the client browser and logged. For any nonzero HRESULT value, the URL field can contain description text to be displayed to the user in the CMS-supplied join-error page.

The CTP needs to decide what criteria, such as an overbooked conference, define whether the client browser has access to the conference.

Note that a pointer to the conference profile is not passed in the call to this method, unlike calls to the PreJoinRequest and PostJoinRequest methods. This happens because the StartConference method, which is passed the meeting ID and a pointer to the profile, is called before the join request is called. The CTP needs to keep track of this association if it needs access to the profile for this method.


IConferenceTechnologyProvider::PreJoinRequest

This method allows a client browser specified by the IConferenceAttendee interface to request joining a conference (specified by the IConferenceProfile interface) that has not yet started.

Syntax

HRESULT PreJoinRequest([in] IConferenceProfile *pProfile,
[in] IConferenceAttendee *pAttendee,
[out] BSTR *pURL);

Parameters

pProfile
[in] An IConferenceProfile interface pointer specifying the requested meeting.
pAttendee
[in] An IConferenceAttendee interface specifying the attendee requesting to join the meeting.
pURL
[out] A URL for the conferencing Web page containing the response to the PreJoinRequest method.

Return Values

S_OK upon success; otherwise, other HRESULT values upon failure.

Remarks

This method gives the CTP the opportunity to return information regarding the conference before the conference’s start time. For example, a telephone conference may return the telephone number and access code that the client browser can dial to join the conference. The CMS defines a custom error page for the CTP if this method returns an error value.


IConferenceTechnologyProvider::PostJoinRequest

This method allows a client browser specified by the IConferenceAttendee interface to request joining a conference—specified by the IConferenceProfile interface—that has finished.

Syntax

HRESULT PostJoinRequest([in] IConferenceProfile *Profile,
[in] IConferenceAttendee *Attendee,
[out] BSTR *pURL);

Parameters

Profile
[in] An IConferenceProfile interface pointer specifying the requested meeting.
Attendee
[in] An IConferenceAttendee interface specifying the attendee requesting to join the meeting.
pURL
[out] A URL for the conferencing Web page containing the response to the PreJoinRequest method.

Return Values

S_OK upon success; otherwise, other HRESULT values upon failure.

Remarks

This method provides client browsers with information regarding a conference that has ended. An example is a telephony conferencing provider that returns a page giving access to a recording of the meeting. The CMS defines a custom error page for the CTP if this method returns an error value.


IConferenceTechnologyProvider::ConfirmScheduleRequest

This method updates a conference profile or creates a new one.

Syntax

HRESULT ConfirmScheduleRequest([in] IConferenceProfile *pCProfileNew,
[in] IConferenceProfile * pCProfileOld,
[in] MODIFICATION_TYPE mType,
[out] BOOLEAN * fDeclineConference,
[out] BSTR * szURLReason);

Parameters

pCProfileNew
[in] An IConferenceProfile interface pointer specifying the updated or new profile for the target conference.
pCProfileOld
[in] An IConferenceProfile interface pointer specifying the conference to update. This parameter is NULL if this method is called to create a new conference.
mType
[in] The requested modification type, MODIFICATION_TYPE, which can be add (CONFERENCE_ADD) or update (CONFERENCE_MODIFY).
fDeclineConference
[out] Upon success of the update request, this flag is set to FALSE; otherwise, it is set to TRUE.
szURLReason
[out] Upon failure, a string representing the URL of the provider’s reason for the failure or NULL upon success.

Return Values

S_OK upon success; otherwise, other HRESULT values upon failure.

Remarks

If the ConfirmScheduleRequest method is called to create a new conference profile, the pCProfileOld parameter is NULL, and the mType parameter is CONFERENCE_ADD. If ConfirmScheduleRequest is called to modify an existing conference profile, the pCProfileOld parameter is a pointer to the old conference profile object, the pCProfileNew parameter is a pointer to the new conference profile object, and the mType parameter is CONFERENCE_MODIFY.

Upon successful addition or update of a conference profile, the fDeclineConference parameter needs to be set to FALSE; otherwise, it needs be set to TRUE and the szURLReason parameter is a link to the provider’s reason for failure.

The following enumerator defines the modification types:

typedef enum _MODIFICATION_TYPE
{
CONFERENCE_ADD,
CONFERENCE_MODIFY
} MODIFICATION_TYPE;

If the CTP maintains its own internal free/busy state, the state needs to be updated during this method call. If the free/busy state for the conference’s duration is changed from busy to free or from free to busy, the CTP needs to signal the CMS that it needs to republish the free/busy state by calling the IConferenceManager::AvailabilityUpdateRequest method.

See Also

IConferenceManager::AvailabilityUpdateRequest

IConferenceTechnologyProvider::AbortScheduleRequest


IConferenceTechnologyProvider::AbortScheduleRequest

This method is used to roll back conference updates and additions in case of ConfirmScheduleRequest failure.

Syntax

HRESULT AbortScheduleRequest([in] IConferenceProfile *pCProfileNew,
[in] IConferenceProfile * pCProfileOld,
[in] MODIFICATION_TYPE mType);

Parameters

pCProfileNew
[in] An IConferenceProfile interface pointer specifying the updated profile for the target conference. This interface pointer must be the same one passed in ConfirmScheduleRequest.
pCProfileOld
[in] An IConferenceProfile interface pointer specifying the conference to update. This interface pointer must be the same one passed in ConfirmScheduleRequest.
mType
[in] The requested modification type, MODIFICATION_TYPE, which can be add (CONFERENCE_ADD) or update (CONFERENCE_MODIFY). This parameter must be the same value passed in the ConfirmScheduleRequest method.

Remarks

If the CMS receives a failure for a ConfirmScheduleRequest call, the CMS calls the AbortScheduleRequest method for all the successful updates and additions performed so far to roll them back. If the CTP maintains its own internal free/busy state, it needs to be updated to reflect the change. The CMS passes the AbortScheduleRequest method the same parameters that were passed in during the successful ConfirmScheduleRequest calls.


CMS Administration Object

The ICMSConfiguration interface is an in-Process COM component that supports free and apartment threading models and can be used from any scripting or automation language. The configuration object is the only creatable object in the library. The library runs within the security context of the user who created the object. Properties within the model honor the security attributes assigned to the associated DS object and attributes.


ICMSConfiguration

This automation object represents a CMS Configuration object.

Methods

The ICMSConfiguration interface contains the following methods:

ICMSConfiguration::GetKnownZones

ICMSConfiguration::GetZone

ICMSConfiguration::RemoveZone

ICMSConfiguration::RegisterNotifyEvent

ICMSConfiguration::RevokeNotification

© 2000-2001 Microsoft Corporation. All rights reserved.


ICMSConfiguration::GetKnownZones

This method returns an array of names of all conferencing zones (Windows NT sites) defined for the organization.

Syntax

HRESULT GetKnownZones([out] VARIANT * KnownZones);

Parameters

KnownZones
[out] A variant of a safe array of BSTR values containing a list of the conferencing zones.

Return Values

Return code | Meaning
S_OK | The call returned successfully.
E_OUTOFMEMORY | Memory allocation failed during the request.
E_POINTER | The out parameter is NULL.
Other HRESULTs | Standard COM error codes.


ICMSConfiguration::GetZone

This method returns an interface to the configuration object for the requested zone, or to the default zone if the ZoneName parameter is not specified.

Syntax

HRESULT GetZone([in] BSTR ZoneName,
[out] VARIANT *Zone );

Parameters

ZoneName
[in] A string representing the requested zone configuration object, or an empty (“”) string to obtain the default zone.
Zone
[out] Upon success, a variant containing the IDispatch interface of the requested ICMSZone object.

Return Values

Return code | Meaning
S_OK | The call returned successfully.
E_OUTOFMEMORY | Memory allocation failed during the request.
E_POINTER | The in or out parameter is NULL.
Other HRESULTs | Standard COM error codes.

Remarks

Due to marshaling, if an empty string is passed, it must be in BSTR format, not LPTSTR format.


ICMSConfiguration::RemoveZone -- Reserved

Platform SDK: Exchange 2000 Server

ICMSConfiguration::RemoveZone — Reserved

© 2000-2001 Microsoft Corporation. All rights reserved.


ICMSConfiguration::RegisterNotifyEvent

This method provides registration for a generic set of notifications for CMS configuration changes.

Syntax

HRESULT RegisterNotifyEvent(
[in] IConferenceCallback *pCallBack,
[in] BSTR Zone,
[in] LONG Events,
[in] long srcCookie,
[out,retval] long *destCookie);

Parameters

pCallBack
[in] The callback interface pointer.
Zone
[in] The zone. It can be NULL for all zones, it can be an empty string (“”) for the local zone, or it can specify a zone name.
Events
[in] An event mask of CMSNOTIF_EVENTS. For more information, see the Remarks section.
srcCookie
[in] A long value specified by the CTP for notification registration.
destCookie
[out] Upon success, this parameter is set to a unique value specifying the instance of the registration. This value must be passed to the RevokeNotification method to disable notifications for the registered events.

Return Values

Return code | Meaning
S_OK | The call returned successfully.
E_INVALIDARG | An invalid argument was passed in. One of the arguments passed in was NULL or didn’t contain the appropriate pointer value.
E_OUTOFMEMORY | Memory allocation failed during the request.
E_POINTER | The out parameter is NULL.
E_UNEXPECTED | The event thread failed to initialize successfully.

Remarks

The following enumerator defines CMS notifications:

typedef enum CMSNOTIF_EVENTS {
CMSNOTIF_ZONEPROPERTYADDED     = 0x0001,
CMSNOTIF_ZONEPROPERTYDELETED    = 0x0002,
CMSNOTIF_ZONEPROPERTYCHANGED    = 0x0004,
CMSNOTIF_TECHNOLOGYPROVIDERADDED  = 0x0008,
CMSNOTIF_TECHNOLOGYPROVIDERDELETED = 0x0010,
CMSNOTIF_TECHNOLOGYPROVIDERCHANGED = 0x0020,
CMSNOTIF_RESOURCEADDED       = 0x0040,
CMSNOTIF_RESOURCEDELETED      = 0x0080,
CMSNOTIF_RESOURCECHANGED      = 0x0100,
CMSNOTIF_MASTERALIASCHANGED    = 0x0200,
} CMSNOTIFEVENTS;

Multiple events can be registered by setting their values in the Events parameter. The destCookie parameter is used to revoke this binding. If multiple events were set in the event mask, all events are revoked. The calling process can use the srcCookie parameter to distinguish specific event registrations during the associated callback.

See Also

ICMSConfiguration::RevokeNotification

© 2000-2001 Microsoft Corporation. All rights reserved.


ICMSConfiguration::RevokeNotification

This method disables an event notification callback.

Syntax

HRESULT RevokeNotification([in] long destCookie);

Parameters

destCookie
[in] A value specifying the instance of the registration. A successful call to the RegisterNotifyEvent method generates the destCookie value.

Return Values

Return code | Meaning
S_OK | The call returned successfully.
E_INVALIDARG | An invalid argument was passed in. The destCookie parameter didn’t contain the appropriate value.
E_UNEXPECTED | The event thread was not initialized successfully.

Remarks

The destCookie parameter specifies the instance of the registration. After a registration has been revoked, the cookie is invalid and must not be used again (because the CMS may reuse the value for a subsequent binding). If the registration includes multiple events, all events associated with the destCookie are revoked. If the same events are registered against another destCookie, the callbacks are unaffected.


ICMSAdministration -- Reserved

Platform SDK: Exchange 2000 Server

ICMSAdministration — Reserved

The ICMSAdministration interface is reserved.

Methods

The ICMSAdministration interfaces has the following reserved methods:

GetKnownGroups

MoveZone

GetKnownZonesByGroup

© 2000-2001 Microsoft Corporation. All rights reserved.


ICMSZone

This automation object represents a CMS Zone object.

Methods

The ICMSZONE interface has the following methods:

ICMSZone::GetHostServer

ICMSZone::SetHostServer —Reserved

ICMSZone::GetResourceMailboxes

ICMSZone::GetProviderClassIDs

ICMSZone::GetProviderConfiguration

ICMSZone::GetConferenceLocator

ICMSZone::SetServiceState —Reserved

ICMSZone::GetServiceState

ICMSZone::Commit

URLFromCGOID —Reserved

Properties

The ICMSZone interface has the following properties:

Name | Type | Access
ICMSZone::ZoneName | String | Read-only
ICMSZone::AvailableHostServers | Safe array of BSTR values | Read/write
ICMSZone::MasterDisplayName | String | Read-only
ICMSZone::MasterLegacyDN | String | Read-only
MasterEmailAddress-Reserved | String | Write-only—
ICMSZone::EnableTimeExtensionRequests | Boolean | Read/write
ICMSZone::EnableResourceUpdateRequests | Boolean | Read/write
ICMSZone::WebServer | String | Read/write
ICMSZone::GracePeriodPrior | Long | Read/write
ICMSZone::GracePeriodAfter | Long | Read/write
ICMSZone::AuditFlags | Long | Read/write


ICMSZone::GetHostServer

This method obtains the computer name of the conferencing server actively running the CMS service.

Syntax

HRESULT GetHostServer([out,retval] BSTR * MachineName);

Parameters

MachineName
[out] A BSTR value representing the computer name.

Return Values

Return code | Meaning
S_OK | The call returned successfully.
E_OUTOFMEMORY | Memory allocation failed during the request.
E_POINTER | The out parameter is NULL.
HRESULT_FROM_WIN32(ERROR_NOT_FOUND) | The host server is not initialized or not found.


ICMSZone::SetHostServer -- Reserved

Platform SDK: Exchange 2000 Server

ICMSZone::SetHostServer — Reserved

© 2000-2001 Microsoft Corporation. All rights reserved.


ICMSZone::GetResourceMailboxes

This method returns a collection of all configured resources for a specific provider CLSID or for all providers.

Syntax

HRESULT GetResourceMailboxes([in] BSTR ProviderClassID,
[out] VARIANT **pResources );

Parameters

ProviderClassID
[in] A BSTR value representing a specific provider CLSID. An empty string requests all providers.
pResources
[out] Upon success, a variant of VT_DISPATCH type containing the IDispatch interface for the ICMSResources collection.

Return Values

Return code | Meaning
S_OK | The call returned successfully.
E_OUTOFMEMORY | Memory allocation failed during the request.
E_POINTER | The out parameter is NULL.
E_UNEXPECTED | An unexpected error occurred.
E_INVALIDARG | An invalid argument was passed in.
HRESULT_FROM_WIN32(ERROR_NOT_FOUND) | The host server is not initialized or not found.

Remarks

The returned collection contains no members if no resources are currently configured.


ICMSZone::GetProviderClassIDs

This method returns an array of the installed provider CLSIDs.

Syntax

HRESULT GetProviderClassIDs([out] VARIANT * ProviderClassID);

Parameters

ProviderClassID
[out] A variant of a safe array of BSTR values representing the installed providers’ CLSID.

Return Values

Return code | Meaning
S_OK | The call returned successfully.
E_OUTOFMEMORY | Memory allocation failed during the request.
E_POINTER | The out parameter is NULL.
E_UNEXPECTED | An unexpected error occurred.


ICMSZone::GetProviderConfiguration

This method returns the CTP configuration object (ICTPConfiguration) for the CTP specified by the provider CLSID.

Syntax

HRESULT GetProviderConfiguration{[in] BSTR ProviderClassID,
[out] VARIANT *pConfig );

Parameters

ProviderClassID
[in] A string specifying the provider CLSID.
pConfig
[out] A variant containing the IDispatch interface of the ICTPConfiguration object for the specified provider CLSID.

Return Values

Return code | Meaning
S_OK | The call returned successfully.
E_OUTOFMEMORY | Memory allocation failed during the request.
E_POINTER | The out parameter is NULL.
E_UNEXPECTED | An unexpected error occurred.
E_INVALIDARG | An invalid argument was passed in.


ICMSZone::GetConferenceLocator

This method returns a reference to the locator interface on the CMS defined by the HostServer property. Scripting languages(for example, on the CMS meeting access page) use this administrative method to communicate to the specific CMS.

Syntax

HRESULT GetConferenceLocator([out] VARIANT * Locator);

Parameters

Locator
[out] A variant containing the IConferenceLocator interface on the CMS.

Return Values

Return code | Meaning
S_OK | The call returned successfully.
E_OUTOFMEMORY | Memory allocation failed during the request.
E_POINTER | The out parameter is NULL.
E_UNEXPECTED | An unexpected error occurred.


ICMSZone::SetServiceState -- Reserved

Platform SDK: Exchange 2000 Server

ICMSZone::SetServiceState — Reserved

© 2000-2001 Microsoft Corporation. All rights reserved.


ICMSZone::GetServiceState

This method obtains the CMS state.

Syntax

HRESULT GetServiceState([out] SERVICESTATE *CurrentState);

Parameters

CurrentState
[out] A SERVICESTATE value. For more information, see the Remarks section.

Return Values

Upon success, this method returns S_OK; otherwise, other HRESULT values are returned upon failure.

Remarks

The following enumerator defines the service states:

typedef enum SERVICE_STATE {
SERVICESTATE_UNKNOWN = -1,  // The state cannot be
                            // (has not been) retrieved.
SERVICESTATE_NOTFOUND = 0,  // The service is not known
                            // on the host server.
SERVICESTATE_STOP   = 1,    // The service is NET stopped.
SERVICESTATE_RUN   = 2,     // The service is NET started.
SERVICESTATE_STOPPING = 3,
SERVICESTATE_STARTING = 4,
} SERVICESTATE;

The call runs synchronously with the remote Service Control Manager (SCM) and any user interface needs to asynchronously display the progress (and timeout just like the SCM).


ICMSZone::Commit

This method causes any updated properties to be written to the DS. Until committed, all property put operations on the zone object are cached within the object and not persisted.

Syntax

HRESULT Commit();

Parameters

None

Return Values

Return code | Meaning
S_OK | The call returned successfully.
E_OUTOFMEMORY | Memory allocation failed during the request.
E_UNEXPECTED | An unexpected error occurred.


ICMSZone::URLFromCGOID-- Reserved

Platform SDK: Exchange 2000 Server

ICMSZone::URLFromCGOID— Reserved

© 2000-2001 Microsoft Corporation. All rights reserved.


ICMSZone::ZoneName Property

This property contains the conference’s site name—based on Windows 2000 sites—in which the CMS service is installed.

Syntax

HRESULT get_ZoneName([out,retval] BSTR *SiteName);

Parameters

SiteName
[out] A string representing the NT site name.

Return Values

Return code | Meaning
S_OK | The call returned successfully.
E_INVALIDARG | An invalid argument was passed in. One of the arguments passed in was NULL or didn’t contain the appropriate pointer value.
E_OUTOFMEMORY | Memory allocation failed during the request.
E_POINTER | The out parameter is NULL.
E_UNEXPECTED | An unexpected error occurred.
HRESULT_FROM_WIN32(ERROR_NOT_FOUND) | The zone name was not initialized.


ICMSZone::AvailableHostServers Property

This property contains an array of computer names that have the CMS service installed.

Syntax

HRESULT get_AvailableHostServers([out,retval] VARIANT *Hosts);

Parameters

Hosts
A variant of a safe array of BSTR values representing the conferencing computer names.

Return Values

Return code | Meaning
S_OK | The call returned successfully.
E_INVALIDARG | An invalid argument was passed in. One of the arguments passed in was NULL or didn’t contain the appropriate pointer value.
E_OUTOFMEMORY | Memory allocation failed during the request.
E_POINTER | The out parameter is NULL.
E_UNEXPECTED | An unexpected error occurred.
HRESULT_FROM_WIN32(ERROR_NOT_FOUND) | The zone name was not initialized.


ICMSZone::MasterDisplayName Property

This property contains the display name for the global calendar mailbox.

Syntax

HRESULT get_MasterDisplayName( [out, retval] BSTR *pVal);

Parameters

pVal
[out] A string representing the master display name.

Return Values

Return code | Meaning
S_OK | The call returned successfully.
E_INVALIDARG | An invalid argument was passed in. One of the arguments passed in was NULL or didn’t contain the appropriate pointer value.
E_OUTOFMEMORY | Memory allocation failed during the request.
E_POINTER | The out parameter is NULL.
E_UNEXPECTED | An unexpected error occurred.
HRESULT_FROM_WIN32(ERROR_NOT_FOUND) | The MasterDisplayName attribute was not set.


ICMSZone::MasterLegacyDN Property

This property contains the master legacy domain name (DN) for the global calendar.

Syntax

HRESULT MasterLegacyDN( [out, retval] BSTR *pVal);

Parameters

pVal
[out] A string representing the master legacy DN.

Return Values

Return code | Meaning
S_OK | The call returned successfully.
E_INVALIDARG | An invalid argument was passed in. One of the arguments passed in was NULL or didn’t contain the appropriate pointer value.
E_OUTOFMEMORY | Memory allocation failed during the request.
E_POINTER | The out parameter is NULL.
E_UNEXPECTED | An unexpected error occurred.
HRESULT_FROM_WIN32(ERROR_NOT_FOUND) | The MasterLegacyDN attribute was not found.


ICMSZone::MasterEmailAddress Property

Platform SDK: Exchange 2000 Server

ICMSZone::MasterEmailAddress Property —Reserved


ICMSZone::EnableTimeExtensionRequests

Platform SDK: Exchange 2000 Server

ICMSZone::EnableTimeExtensionRequests Property

This property contains the administrative setting of whether meeting time modifications are offered to conference organizers. Setting the value to true enables requests.

Syntax

HRESULT get_EnableTimeExtensionRequests( [out] VARIANT_BOOL * bEnableExt);

Parameters

bEnableExt
A Boolean value set to true or false, based on whether meeting time modifications are offered to conference organizers.

Return Values

Return code | Meaning
S_OK | The call returned successfully.
E_OUTOFMEMORY | Memory allocation failed during the request.
E_POINTER | The out parameter is NULL.
E_UNEXPECTED | An unexpected error occurred.


ICMSZone::EnableResourceUpdateRequests

Platform SDK: Exchange 2000 Server

ICMSZone::EnableResourceUpdateRequests Property

This property contains the administrative setting of whether the conference organizer is allowed to change conference resources during the conference.

Syntax

HRESULT get_EnableResourceUpdateRequests(VARIANT_BOOL * pbEnableRes);

Parameters

pbEnableRes
A Boolean value that determines whether the conference organizer is allowed to change conference resources. VARIANT_TRUE enables requests.

Return Values

Return code | Meaning
S_OK | The call returned successfully.
E_OUTOFMEMORY | Memory allocation failed during the request.
E_POINTER | The out parameter is NULL.
E_UNEXPECTED | An unexpected error occurred.


ICMSZone::WebServer Property

This property contains the URL address for a conference. The property value is a string of 0 to 250 characters that is used as the prefix to the meeting’s URL.

Syntax

HRESULT get_WebServer(BSTR URL);

Parameters

URL
A string (0 to 250 characters in length) used as the prefix to the meeting’s URL.

Return Values

Return code | Meaning
S_OK | The call returned successfully.
E_OUTOFMEMORY | Memory allocation failed during the request.
E_POINTER | The out parameter is NULL.
E_UNEXPECTED | An unexpected error occurred.

Remarks

The CMS replicates the current value onto each resource mailbox in the zone.


ICMSZone::GracePeriodPrior Property

This property contains an administratively configured setting between 0 and 60 minutes (in seconds). The default is 1,200 seconds, or 20 minutes. The conference starts at the conference’s start time minus this grace period.

Syntax

HRESULT get_GracePeriodPrior(long * Seconds);

Parameters

Seconds
The number of seconds specifying the grace period before the meeting’s start time. The range of this value is 0 to 3,600.

Return Values

Return code | Meaning
S_OK | The call returned successfully.
E_OUTOFMEMORY | Memory allocation failed during the request.
E_POINTER | The out parameter is NULL.
E_UNEXPECTED | An unexpected error occurred.


ICMSZone::GracePeriodAfter Property

This property contains a value between 0 and 60 minutes (in seconds) that is added to every schedule’s end time. The default is 0. The conference ends at the conference’s end time plus this grace period.

Syntax

HRESULT get_GracePeriodAfter(long * Seconds);

Parameters

Seconds
The number of seconds specifying the grace period after the meeting’s end time for the meeting to terminate. The range of this value is 0 to 3,600. The default value is 0.

Return Values

Return code | Meaning
S_OK | The call returned successfully.
E_OUTOFMEMORY | Memory allocation failed during the request.
E_POINTER | The out parameter is NULL.
E_UNEXPECTED | An unexpected error occurred.


ICMSZone::AuditFlags Property

This property contains the events that need to be logged to the Exchange Conferencing Server log.

Syntax

HRESULT get_AuditFlags(long * Flag);

Parameters

Flag
A CMS_LOGGING_FLAGS value that specifies which events to audit. For more information, see the Remarks section.

Return Values

Return code | Meaning
S_OK | The call returned successfully.
E_OUTOFMEMORY | Memory allocation failed during the request.
E_POINTER | The out parameter is NULL.
E_UNEXPECTED | An unexpected error occurred.

Remarks

The following enumerator defines the logging flags:

typedef enum _CMS_LOGGING_FLAGS{
LOG_ON           = 0x00000400,
LOG_CONFERENCE_SCHEDULED  = 0x00000200,
LOG_CONFERENCE_UPDATED   = 0x00000100,
LOG_CONFERENCE_CANCELLED  = 0x00000080,
LOG_AVAILABILITY_CHANGED  = 0x00000040,
LOG_CLIENT_CONNECTED    = 0x00000020,
LOG_EARLYLATE_CONNECTION  = 0x00000010,
LOG_AUTH_FAILURE      = 0x00000008,
LOG_CONNECTION_FAILED    = 0x00000004,
LOG_TIMEEXTEND_REQUEST   = 0x00000002,
LOG_RESOURCEEXTEND_REQUEST = 0x00000001,
} CMS_LOGGING_FLAGS;


ICMSResources

This object defines a scriptable, automation compatible collection of resources.

Properties

The ICMSResources interface has the following properties:

Name | Type | Access
ICMSResources::Count | Long | Read-only
ICMSResources::Item (default property) | ICMSResource object | Read/write
ICMSResources::NewEnum | IUnknown | Read-only


ICMSResources::Count Property

This property contains the count of items in the collection.

Syntax

HRESULT get_Count( [out, retval] long * Count );

Parameters

Count
The number of ICMSResources objects in the collection.

Return Values

S_OK upon success; otherwise, other HRESULT values upon failure.


ICMSResources::Item

This property contains a single ICMSResources object from the collection.

Syntax

HRESULT get_Item([in] VARIANT indexKey,
[out, retval] ICMSResource **pVal);

Parameters

indexKey
[in] The index key can be either a numeric value (VT_I2 or VT_I4), an index into collection, or a BSTR value (VT_BSTR) representing the e-mail name of a contained profile. The numeric index starts at 1. Use either a string or a numeric index, but not both.
pVal
[out] Upon success, a valid ICMSResources interface if one is found.

Return Values

S_OK upon success; otherwise, other HRESULT values upon failure.


ICMSResources::NewEnum Property

This property contains the automation compatible enumerator for the collection.

Syntax

HRESULT get__NewEnum([out, retval] IUnknown **pVal);

Parameters

pVal
[out] A pointer to the enumerator object’s IUnknown interface.

Return Values

S_OK upon success; otherwise, other HRESULT values upon failure.

Remarks

This object is returned even if no members exist (the count is zero).


ICMSResource

This automation object provides access to the resource-specific properties on a mail-enabled user account that has been flagged as a resource mailbox. The behavior of this interface differs based on how it is obtained. This interface needs to be used for read-only purposes if it is obtained from the IConferenceProfile interface because IConferenceProfile is an object that contains a snapshot of the definition of a meeting in the profile store. If ICMSResource is obtained from ICMSZone, its write properties and methods are valid because ICMSResource writes directly to the DS. Note that the caller of the write methods on the ICMSResource object must be running in a context that has administrative privileges allowing writing to the DS.

A CTP querying for specific property values needs to do so by using an ICMSResource interface that is obtained from IConferenceProfile. This enables the CTP to obtain the needed properties’ values as they were configured from the conference profile snapshot. An MMC snap-in extension that configures CTP properties is passed an ICMSResource interface that was obtained from an ICMSZone interface This enables the snap-in extension to configure CTP properties if it is running under an account with privileges to write to the DS.

Methods

The ICMSResource interface has the following methods:

ICMSResource::GetProviderPropertySet

ICMSResource::SetProviderProperty

ICMSResource::Commit

ICMSResource::GetAddressType

Properties

The ICMSResource interface has the following properties.

Name | Type | Access
ICMSResource::DisplayName | String | Read-only
ICMSResource::EmailName | String | Read-only
ICMSResource::Description | String | Read-only
ICMSResource::ControllingZone | String | Read-only
ICMSResource::RepresentProviders | Safe array of BSTR values | Read-only


ICMSResource::GetProviderPropertySet

This method returns an array of property pairs defined on the resource mailbox for a specific PropertyClassID.

Syntax

HRESULT GetProviderPropertySet([in] BSTR ProviderClassID,
[out]VARIANT *PropertyPairs);

Parameters

ProviderClassID
[in] A string representing the provider CLSID.
PropertyPairs
[out] A safe array of BSTR values representing property pairs.

Return Values

Return code | Meaning
S_OK | The call returned successfully.
E_POINTER | The out parameter is NULL.
E_INVALIDARG | An input argument is invalid, such as ProviderClassID not found.
E_OUTOFMEMORY | Memory allocation failed during the request.
DISP_E_BADINDEX | The specified index is invalid.

Remarks

Each pair is formatted as property_name=property value. The name is specified when the property is added to the set.


ICMSResource::SetProviderProperty

This method sets a property pair on the resource mailbox for a specific ProviderClassID.

Syntax

HRESULT SetProviderProperty([in] BSTR ProviderClassID,
[in] BSTR PropertyName,
[in] VARIANT PropertyValue);

Parameters

ProviderClassID
A string representing the provider CLSID.
PropertyName
A string of 1 to 16 characters, representing the property name.
PropertyValue
A variant representing the property value to set.

Return Values

Return code | Meaning
S_OK | The call returned successfully.
E_INVALIDARG | Invalid input arguments, such as ProviderClassID not found, invalid properties, or properties not found.
E_OUTOFMEMORY | Memory allocation failed during the request.
DISP_E_BADINDEX | The specified index is invalid.

Remarks

The property name is between 1 and 16 alphanumeric characters. The defined value is stored in the resource.

The VARIANT value must contain either a numeric or a string type, as limited by the property set schema defined in the CTP DS object.

Setting a property to VARIANT(VT_NULL) removes the property from the property set. Beware that setting this could remove one of the CTP’s standard properties—for example, size—that the CTP uses to identify a resource.

The total length of the property set, including CLSID and field delimiters, is limited to 2,048 characters. Any attempt to set a property above this limit may fail.

To enable UI-based configuration of properties set by this method, make sure that ICTPSpecifyResourcePropertyPages is supported on the CTP’s snap-in extension.

This property is not valid if the ICMSResource interface is obtained from the IConferenceProfile interface, because IConferenceProfile is a snapshot of the scheduled conference and doesn’t have access to the DS where properties are stored. Furthermore, for this call to succeed, the call must be made in a process that is running under a security context that allows writing to the DS.

See Also

ICTPSpecifyResourcePropertyPages interface


ICMSResource::Commit

This method writes any updated properties to the DS.

Syntax

HRESULT Commit();

Parameters

None

Return Values

Return code | Meaning
S_OK | The call returned successfully.
E_OUTOFMEMORY | Memory allocation failed during the request.
E_UNEXPECTED | An unexpected error occurred.

Remarks

All property updates are cached within the object until this commit method is called, at which point they are written to the DS.

This property is not valid if the ICMSResource interface is obtained from the IConferenceProfile interface, because IConferenceProfile is a snapshot of the scheduled conference and doesn’t have access to the DS where properties are stored. Furthermore, for this call to succeed, the call must be made in a process that is running under a security context that allows writing to the DS.


ICMSResource::GetAddressType -- Reserved

Platform SDK: Exchange 2000 Server

ICMSResource::GetAddressType — Reserved

© 2000-2001 Microsoft Corporation. All rights reserved.


ICMSResource::DisplayName Property

This property contains the display name of the NT account of the associated resource.

Syntax

HRESULT get_DisplayName([out, retval] BSTR *Name);

Parameters

Name
[out] A string representing the display name property.

Return Values

Return code | Meaning
S_OK | The call returned successfully.
E_OUTOFMEMORY | Memory allocation failed during the request.
E_POINTER | The out parameter is NULL.
E_UNEXPECTED | An unexpected error occurred.
E_FAIL | The requested property is not found or is invalid.


ICMSResource::EmailName Property

This property contains the Windows NT account name of the associated resource mailbox.

Syntax

HRESULT get_DisplayName([out, retval] BSTR *Name);

Parameters

Name
[out] A string representing the NT account name of the associated mailbox.

Return Values

Return code | Meaning
S_OK | The call returned successfully.
E_OUTOFMEMORY | Memory allocation failed during the request.
E_POINTER | The out parameter is NULL.
E_UNEXPECTED | An unexpected error occurred.
E_FAIL | The requested property is not found or is invalid.


ICMSResource::Description Property

This property contains the description field of the NT account of the associated resource.

Syntax

HRESULT get_Description([out, retval] BSTR *pVal);

Parameters

PVal
[out] A string representing the resource’s description.

Return Values

Return code | Meaning
S_OK | The call returned successfully.
E_OUTOFMEMORY | Memory allocation failed during the request.
E_POINTER | The out parameter is NULL.
E_UNEXPECTED | An unexpected error occurred.
E_FAIL | The requested property is not found or is invalid.


ICMSResource::ControllingZone Property

This property contains the zone (Windows 2000 site name) from which the associated CMS monitors meeting requests.

Syntax

HRESULT get_ControllingZone(BSTR *AssignedZone);

Parameters

AssignedZone
A string representing the zone from which the associated CMS monitors meeting requests.

Return Values

Return code | Meaning
S_OK | The call returned successfully.
E_OUTOFMEMORY | Memory allocation failed during the request.
E_POINTER | The out parameter is NULL.
E_UNEXPECTED | An unexpected error occurred.

Remarks

This property is valid only if the ICMSResource interface is obtained from the ICMSZone interface. This property is not valid if the ICMSResource interface is obtained from the IConferenceProfile interface, because the conference profile reflects a snapshot of the conference configuration, not a run-time instance of the conference.


ICMSResource::RepresentProviders Property

This property contains an array of ProviderClassID values associated with the resource represented as a GUID-formatted string. Note that only the first five providers’ CLSIDs are persisted.

Syntax

HRESULT get_RepresentProviders( VARIANT * ProviderClassIDs);

Parameters

ProviderClassIDs
[out] A variant of a safe array of BSTR values representing the providers’ CLSIDs associated with the resource.

Return Values

Return code | Meaning
S_OK | The call returned successfully.
E_OUTOFMEMORY | Memory allocation failed during the request.
E_POINTER | The out parameter is NULL.
E_UNEXPECTED | An unexpected error occurred.

Remarks

Each of the provider CLSIDs obtained in the safe array corresponds to a value returned by the IConferenceTechnologyProvider::ProviderClassID method for each CTP associated with the resource.


ICTPConfiguration

The ICTPConfiguration automation object provides a convenient and read-only, representation of the CTP configuration in the Active Directory tree of Exchange Conferencing Server.

Properties

The ICTPConfiguration interface provides the following properties.

Name | Type | Access
ICTPConfiguration::ProviderClassID | String | Read-only
ICTPConfiguration::DisplayName | String | Read-only
ICTPConfiguration::ClassID | String | Read-only
ICTPConfiguration::SnapInClassID | String | Read-only
ICTPConfiguration::FrameSizeHint | String | Read-only
ICTPConfiguration::AuthenticateAccess | String | Read-only


ICTPConfiguration::ProviderClassID Property

This property contains the CTP’s CLSID.

Syntax

HRESULT get_ProviderClassID([out,retval] BSTR *GUID);

Parameters

GUID
[out] A provider’s CLSID in a string format.

Return Values

S_OK if successful; otherwise, other HRESULT calues upon failure.

Remarks

The value of this field is used to associate a CTP with a resource. The CTP must maintain the same ProviderClassID value for the life of the provider’s installation with the CMS.

Because the CMS does not use the value of this property to instantiate the CTP, the CTP can be upgraded without the need to reconfigure resources.


ICTPConfiguration::DisplayName Property

This property is an alphanumeric string of 1 to 32 used to identify the provider.

Syntax

HRESULT get_DisplayName([out,retval] BSTR *Name);

Parameters

Name
The provider’s display name, which is an alphanumeric string of 1 to 32 characters.

Return Values

S_OK if successful; otherwise, other HRESULT values upon failure.


ICTPConfiguration::ClassID Property

This property is a string representing the CLSID of the component that implements the CTP interface. The CMS uses this CLSID to instantiate the CTP.

Syntax

HRESULT get_ClassID([out,retval] BSTR *GUID);

Parameters

GUID
A string representing the CLSID of the CTP interface.

Return Values

S_OK if successful; otherwise, other HRESULT values upon failure.


ICTPConfiguration::SnapInClassID Property

A string representing the CLSID of the component that implements the CTP’s administrative snap-in extension. An empty string indicates that the provider does not have an associated snap-in extension.

Syntax

HRESULT get_SnapInClassID([out,retval] BSTR *GUID);

Parameters

GUID
A string representing the CLSID of the CTP’s snap-in extension object, if one exists.

Return Values

S_OK if successful; otherwise, other HRESULT values upon failure.


ICTPConfiguration::FrameSizeHint Property

This property contains the percentage that the CMS meeting access page needs to use when scaling the CTP frame set.

Syntax

HRESULT get_FrameSizeHint(OUT long *plFrameHint);

Parameters

plFrameHint
[out] A long value representing the percentage used by the CMS meeting access page to scale the CTP frame set.

Return Values

S_OK if successful; otherwise, other HRESULT values upon failure.


ICTPConfiguration::AuthenticateAccess Property

This property is set to true if the corresponding CTP DS attribute is true, defining that the CMS meeting access page (by means of the conference locator does not need browser authentication when the client browser is accessing a private conference.

Syntax

HRESULT get_AuthenticateAccess(OUT VARIANT_BOOL *fAuthenticate)

Parameters

fAuthenticate
[out] Set to VARIANT_TRUE if the meeting access page is authenticated, VARIANT_FALSE otherwise.

Return Values

S_OK if successful; otherwise, other HRESULT values upon failure.

Remarks

The conference’s access page is authenticated if any CTP associated with any conference resource for that conference has the AuthenticateAccess attribute set.


ICTPSpecifyResourcePropertyPages

This interface is implemented on the CTP’s MMC snap-in extension to enable the CMS to access and configure profile properties on a per-conference basis.

Method

The ICTPSpecifyResourcePropertyPages interface has the following method:

ICTPSpecifyResourcePropertyPages::GetPages


ICTPSpecifyResourcePropertyPages::GetPages

The GetPages method enables the Exchange Conferencing MMC-based UI to dynamically create property pates for the CTP's properties defined at the resource scope.

Syntax

HRESULT GetPages([out, retval] CAUUID *pPages);

Parameters

pPages
[out] The CAUUID structure is a counted array of universally unique identifier (UUID) or globally unique identifier (GUID) types. As in the ISpecifyPropertyPages:: GetPages method, it is used to receive an array of CLSID values for the property pages that the object needs displayed. For more information about the structure, see the Remarks section.

Return Values

S_OK if successful; otherwise, other HRESULT values upon failure.

Remarks

The CAUUID structure has the following form:

typedef struct tagCAUUID{
ULONG cElems;
// Size of the array to which pElems
// points.
GUID FAR* pElems;
// Pointer to an array of UUID values,
// each of which specifies a CLSID
// of a particular property page.
// This array is allocated by the call
// recipient by using CoTaskMemAlloc
// and is freed by the caller by using
// CoTaskMemFree.
} CAUUID; ]

See Also

ISpecifyPropertyPages::GetPages in MSDN Library


ICTPLocaleInformation

This IUnknown-derived interface is implemented on the CTP’s MMC snap-in extension to provide access to the CTP-specific localized information.

Methods

The ICTPLocaleInformation interface has the following method:

ICTPLocaleInformation::DisplayName

© 2000-2001 Microsoft Corporation. All rights reserved.


ICTPLocaleInformation::DisplayName

Syntax

HRESULT DisplayName([out, retval] BSTR *pVal);

Parameters

pVal
[out] A localized string representing the CTP’s display name.

Return Values

S_OK if successful; otherwise, other HRESULT values upon failure.


Release Notes for Exchange 2000 Server

The topics in this section provide corrections, information about known bugs, and late breaking news pertaining to the Microsoft Exchange 2000 Server.

Web Storage System

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.


Web Storage System

This section describes known issues with the Microsoft Web Storage System at the time the SDK was released.

FrontPage 2000 Web

The Application Deployment Wizard cannot be used to package Microsoft® FrontPage® Webs. If you use FrontPage to create and manage a Web site, you cannot use the Application Deployment Wizard to package the Web application. Attempting to package a FrontPage Web with the Application Deployment Wizard may result in a 403 Forbidden error.

© 2000-2001 Microsoft Corporation. All rights reserved. Terms of use.